package de.urszeidler.shr5.ecp.editor.pages;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.nebula.paperclips.core.PaperClips;
import org.eclipse.nebula.paperclips.core.PrintJob;
import org.eclipse.nebula.paperclips.widgets.PrintPreview;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.wb.swt.ResourceManager;
import de.urszeidler.eclipse.shr5.Shr5Factory;
import de.urszeidler.eclipse.shr5Management.NonPlayerCharacter;
import de.urszeidler.eclipse.shr5Management.Shr5managementFactory;
import de.urszeidler.shr5.ecp.Activator;
import de.urszeidler.shr5.ecp.preferences.PreferenceConstants;
import de.urszeidler.shr5.ecp.printer.BasicPrinter.PrintFactory;
/**
* This a a shameless copy of
* http://code.google.com/p/swt-paperclips/source/browse/net.sf.paperclips.examples/src/net/sf/paperclips/examples/Snippet7.java
* only adapted for the FormEditor and multi use.
*
* @author urs
*/
public class PrintPreviewPage extends FormPage {
private Button previousPage;
private Label pageNumber;
private Button nextPage;
private ScrolledComposite scroll;
private PrintPreview preview;
private double[] scrollingPosition;
protected PrintJob printJob;
private Display display;
protected Shell shell;
private PrintFactory print;
private IPreferenceStore store;
/**
* Create the form page.
*
* @param id
* @param title
*/
public PrintPreviewPage(String id, String title) {
super(id, title);
NonPlayerCharacter character = Shr5managementFactory.eINSTANCE.createNonPlayerCharacter();
character.setPersona(Shr5Factory.eINSTANCE.createMudanPersona());
// print = PersonaPrinter.getInstance().printCharacterSheet(character);
}
/**
* Create the form page.
*
* @param editor
* @param id
* @param title
* @wbp.parser.constructor
* @wbp.eval.method.parameter id "Some id"
* @wbp.eval.method.parameter title "Some title"
*/
public PrintPreviewPage(FormEditor editor, String id, String title) {
super(editor, id, title);
NonPlayerCharacter character = Shr5managementFactory.eINSTANCE.createNonPlayerCharacter();
character.setPersona(Shr5Factory.eINSTANCE.createMudanPersona());
// print = PersonaPrinter.getInstance().printCharacterSheet(character);
}
/**
* Create the form page.
*
* @param editor
* @param id
* @param title
*/
public PrintPreviewPage(FormEditor editor, String id, String title, PrintFactory print) {
super(editor, id, title);
NonPlayerCharacter character = Shr5managementFactory.eINSTANCE.createNonPlayerCharacter();
character.setPersona(Shr5Factory.eINSTANCE.createMudanPersona());
this.print = print;
store = Activator.getDefault().getPreferenceStore();
// store.addPropertyChangeListener(this);
}
/**
* Create contents of the form.
*
* @param managedForm
*/
@Override
protected void createFormContent(IManagedForm managedForm) {
managedForm.getForm().setDelayedReflow(true);
FormToolkit toolkit = managedForm.getToolkit();
ScrolledForm form = managedForm.getForm();
form.setText("Printer Preview for :" + print.getPrintTitel());
Composite body = form.getBody();
toolkit.decorateFormHeading(form.getForm());
toolkit.paintBordersFor(body);
managedForm.getForm().getBody().setLayout(new GridLayout(1, false));
// Composite body2 = form.;
display = Display.getCurrent();
shell = display.getActiveShell();
createButtonPanel(body).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
createScrollingPreview(body).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
updateJob();
managedForm.reflow(true);
}
protected void updateJob() {
printJob = new PrintJob(print.getPrintTitel(), print.createPrinter());
printJob.setMargins(store.getInt(PreferenceConstants.FOOTER_GAP));
preview.setPrintJob(printJob);
forgetScrollingPosition();
updatePreviewSize();
updatePageNumber();
}
private Control createButtonPanel(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(17, false);
layout.marginWidth = layout.marginHeight = 0;
composite.setLayout(layout);
createTextButton(composite, "refresh", "Portrait Orientation", new Listener() {
public void handleEvent(Event event) {
updateJob();
// forgetScrollingPosition();
// updatePreviewSize();
// updatePageNumber();
}
});
previousPage = createIconButton(composite, "backward_nav.gif", "Previous Page", new Listener() {
public void handleEvent(Event event) {
setPreviewPageIndex(preview.getPageIndex() - preview.getHorizontalPageCount() * preview.getVerticalPageCount());
}
});
pageNumber = new Label(composite, SWT.NONE);
nextPage = createIconButton(composite, "forward_nav.gif", "Next Page", new Listener() {
public void handleEvent(Event event) {
setPreviewPageIndex(preview.getPageIndex() + preview.getHorizontalPageCount() * preview.getVerticalPageCount());
}
});
createIconButton(composite, "fit_horizontal.gif", "Fit Width", new Listener() {
public void handleEvent(Event event) {
preview.setFitHorizontal(true);
preview.setFitVertical(false);
rememberScrollingPosition();
updatePreviewSize();
restoreScrollingPosition();
}
});
createIconButton(composite, "fit_vertical.gif", "Fit Height", new Listener() {
public void handleEvent(Event event) {
preview.setFitVertical(true);
preview.setFitHorizontal(false);
rememberScrollingPosition();
updatePreviewSize();
restoreScrollingPosition();
}
});
createIconButton(composite, "fit_best.gif", "Fit Window", new Listener() {
public void handleEvent(Event event) {
preview.setFitVertical(true);
preview.setFitHorizontal(true);
rememberScrollingPosition();
updatePreviewSize();
restoreScrollingPosition();
}
});
createIconButton(composite, "zoom_in.gif", "Zoom In", new Listener() {
public void handleEvent(Event event) {
setPreviewScale(preview.getAbsoluteScale() * 1.1f);
}
});
createIconButton(composite, "zoom_out.gif", "Zoom Out", new Listener() {
public void handleEvent(Event event) {
setPreviewScale(preview.getAbsoluteScale() / 1.1f);
}
});
createIconButton(composite, "zoom_scale.gif", "Zoom to Scale", new Listener() {
public void handleEvent(Event event) {
setPreviewScale(1);
}
});
createTextButton(composite, "Port", "Portrait Orientation", new Listener() {
public void handleEvent(Event event) {
printJob.setOrientation(PaperClips.ORIENTATION_PORTRAIT);
preview.setPrintJob(printJob);
forgetScrollingPosition();
updatePreviewSize();
updatePageNumber();
}
});
createTextButton(composite, "Land", "Landscape Orientation", new Listener() {
public void handleEvent(Event event) {
printJob.setOrientation(PaperClips.ORIENTATION_LANDSCAPE);
preview.setPrintJob(printJob);
forgetScrollingPosition();
updatePreviewSize();
updatePageNumber();
}
});
createIconButton(composite, "print_edit.gif", "Print", new Listener() {
public void handleEvent(Event event) {
PrintDialog dialog = new PrintDialog(shell, SWT.NONE);
PrinterData printerData = dialog.open();
if (printerData != null) {
PaperClips.print(printJob, printerData);
preview.setPrinterData(printerData);
}
}
});
createLabel(composite, "Horz Pages");
createPageCountSpinner(composite, new Listener() {
public void handleEvent(Event event) {
preview.setHorizontalPageCount(((Spinner)event.widget).getSelection());
forgetScrollingPosition();
updatePreviewSize();
updatePageNumber();
}
});
createLabel(composite, "Vert Pages");
createPageCountSpinner(composite, new Listener() {
public void handleEvent(Event event) {
preview.setVerticalPageCount(((Spinner)event.widget).getSelection());
forgetScrollingPosition();
updatePreviewSize();
updatePageNumber();
}
});
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
return composite;
}
private Control createScrollingPreview(Composite parent) {
scroll = new ScrolledComposite(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
scroll.setExpandHorizontal(true);
scroll.setExpandVertical(true);
preview = new PrintPreview(scroll, SWT.NONE);
scroll.setContent(preview);
scroll.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
Rectangle bounds = scroll.getClientArea();
scroll.getHorizontalBar().setPageIncrement(bounds.width * 2 / 3);
scroll.getVerticalBar().setPageIncrement(bounds.height * 2 / 3);
if (preview.isFitHorizontal() ^ preview.isFitVertical()) {
rememberScrollingPosition();
updatePreviewSize();
restoreScrollingPosition();
}
}
});
preview.setFitVertical(true);
preview.setFitHorizontal(true);
Listener dragListener = new Listener() {
private final Point dpi = display.getDPI();
private boolean scrollable = false;
private boolean dragging = false;
private Point dragStartScrollOrigin = null;
private Point dragStartMouseAnchor = null;
public void handleEvent(Event event) {
switch (event.type) {
case SWT.Resize:
forgetScrollingPosition();
Rectangle bounds = scroll.getClientArea();
Point size = preview.getSize();
scrollable = size.x > bounds.width || size.y > bounds.height;
if (!scrollable && dragging)
endDragging();
break;
case SWT.MouseDown:
forgetScrollingPosition();
if (scrollable && event.button == 1)
beginDragging(event);
break;
case SWT.MouseMove:
if (dragging) {
forgetScrollingPosition();
Point point = preview.toDisplay(event.x, event.y);
scroll.setOrigin(dragStartScrollOrigin.x + dragStartMouseAnchor.x - point.x, dragStartScrollOrigin.y
+ dragStartMouseAnchor.y - point.y);
}
break;
case SWT.MouseUp:
forgetScrollingPosition();
if (dragging)
endDragging();
break;
case SWT.MouseEnter:
display.addFilter(SWT.MouseWheel, this);
break;
case SWT.MouseWheel:
if (event.count != 0) {
if (scrollable && !dragging && (event.stateMask == SWT.NONE || event.stateMask == SWT.SHIFT)) {
forgetScrollingPosition();
bounds = scroll.getClientArea();
size = preview.getSize();
Point origin = scroll.getOrigin();
int direction = event.count > 0 ? -1 : 1;
// Prefer vertical scrolling unless user is
// pressing Shift
if (size.y > bounds.height && event.stateMask == SWT.NONE)
origin.y += direction * Math.min(dpi.y, bounds.height / 4);
else if (size.x > bounds.width)
origin.x += direction * Math.min(dpi.x, bounds.width / 4);
scroll.setOrigin(origin);
event.doit = false;
} else if (event.stateMask == SWT.CTRL) { // Ctrl+MouseWheel
// ->
// zoom
float scale = preview.getAbsoluteScale();
setPreviewScale(event.count > 0 ? scale / 1.1f : scale * 1.1f);
}
}
break;
case SWT.MouseExit:
display.removeFilter(SWT.MouseWheel, this);
break;
}
}
private void beginDragging(Event event) {
dragStartScrollOrigin = scroll.getOrigin();
dragStartMouseAnchor = preview.toDisplay(event.x, event.y);
dragging = true;
}
private void endDragging() {
dragging = false;
dragStartMouseAnchor = null;
dragStartScrollOrigin = null;
}
};
scroll.addListener(SWT.Resize, dragListener);
preview.addListener(SWT.MouseDown, dragListener);
preview.addListener(SWT.MouseMove, dragListener);
preview.addListener(SWT.MouseUp, dragListener);
// These are for mouse wheel handling
preview.addListener(SWT.MouseEnter, dragListener);
preview.addListener(SWT.MouseExit, dragListener);
return scroll;
}
private Button createIconButton(Composite parent, String imageFilename, String toolTipText, Listener selectionListener) {
Button button = createButton(parent, toolTipText, selectionListener);
button.setImage(createImage(imageFilename));
return button;
}
private Button createTextButton(Composite parent, String text, String toolTipText, Listener selectionListener) {
Button button = createButton(parent, toolTipText, selectionListener);
button.setText(text);
return button;
}
private Button createButton(Composite parent, String toolTipText, Listener selectionListener) {
Button button = new Button(parent, SWT.PUSH);
button.setToolTipText(toolTipText);
button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
button.addListener(SWT.Selection, selectionListener);
return button;
}
private Spinner createPageCountSpinner(Composite parent, Listener selectionListener) {
Spinner spinner = new Spinner(parent, SWT.BORDER);
spinner.setMinimum(1);
spinner.setMaximum(99);
spinner.addListener(SWT.Selection, selectionListener);
return spinner;
}
private void createLabel(Composite parent, String text) {
new Label(parent, SWT.NONE).setText(text);
}
private Image createImage(String filename) {
final Image image = ResourceManager.getPluginImage("de.urszeidler.shr5.ecp", "images/" + filename);
return image;
}
private void updatePageNumber() {
int pageIndex = preview.getPageIndex();
int pageCount = preview.getPageCount();
int visiblePageCount = preview.getHorizontalPageCount() * preview.getVerticalPageCount();
String text = (visiblePageCount > 1 ? "Pages " + (pageIndex + 1) + "-" + Math.min(pageCount, pageIndex + visiblePageCount) : "Page "
+ (pageIndex + 1))
+ " of " + pageCount;
pageNumber.setText(text);
previousPage.setEnabled(pageIndex > 0);
nextPage.setEnabled(pageIndex < pageCount - visiblePageCount);
shell.layout(new Control[]{ pageNumber });
}
private void rememberScrollingPosition() {
Point size = preview.getSize();
if (size.x == 0 || size.y == 0) {
forgetScrollingPosition();
} else if (scrollingPosition == null) {
Point origin = scroll.getOrigin();
scrollingPosition = new double[]{ (double)origin.x / (double)size.x, (double)origin.y / (double)size.y };
}
}
private void forgetScrollingPosition() {
scrollingPosition = null;
}
private void restoreScrollingPosition() {
if (scrollingPosition != null) {
Point size = preview.getSize();
scroll.setOrigin((int)Math.round(scrollingPosition[0] * size.x), (int)Math.round(scrollingPosition[1] * size.y));
}
}
private void updatePreviewSize() {
Point minSize;
Rectangle bounds = scroll.getClientArea();
if (preview.isFitHorizontal()) {
if (preview.isFitVertical())
minSize = new Point(0, 0); // Best fit
else
minSize = new Point(0, preview.computeSize(bounds.width, SWT.DEFAULT).y); // Fit to width
} else {
if (preview.isFitVertical())
minSize = new Point(preview.computeSize(SWT.DEFAULT, bounds.height).x, 0); // Fit to height
else
minSize = preview.computeSize(SWT.DEFAULT, SWT.DEFAULT); // Custom
// scale
}
scroll.setMinSize(minSize);
}
private void setPreviewScale(float scale) {
preview.setFitVertical(false);
preview.setFitHorizontal(false);
preview.setScale(scale);
rememberScrollingPosition();
updatePreviewSize();
restoreScrollingPosition();
}
private void setPreviewPageIndex(int pageIndex) {
preview.setPageIndex(Math.max(Math.min(pageIndex, preview.getPageCount() - 1), 0));
updatePageNumber();
}
}