/* * Copyright (c) 2006 Matthew Hall and others. * 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 * * Contributors: * Matthew Hall - initial API and implementation */ package org.eclipse.nebula.paperclips.core; import org.eclipse.nebula.paperclips.core.internal.util.Util; import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; /** * A print wrapper which prevents its target from being broken into multiple * pieces when printed. If there isn't enough room to print the target in one * piece on the current page (or column, if it's inside a ColumnPrint), it will * be printed on the next page (or column). * * <p> * Care must be taken when using this class to avoid unprintable documents. If * the target of a NoBreakPrint does not fit in the available space on the print * device, the entire document will fail to print. * * @author Matthew Hall */ public class NoBreakPrint implements Print { private final Print target; /** * Constructs a NoBreakPrint with the given target. * * @param target * the print to */ public NoBreakPrint(Print target) { Util.notNull(target); this.target = target; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((target == null) ? 0 : target.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; NoBreakPrint other = (NoBreakPrint) obj; if (target == null) { if (other.target != null) return false; } else if (!target.equals(other.target)) return false; return true; } /** * Returns the print which will not be broken across pages. * * @return the print which will not be broken across pages. */ public Print getTarget() { return target; } public PrintIterator iterator(Device device, GC gc) { return new NoBreakIterator(target.iterator(device, gc)); } } class NoBreakIterator implements PrintIterator { private PrintIterator target; NoBreakIterator(PrintIterator target) { Util.notNull(target); this.target = target; } public PrintIterator copy() { return new NoBreakIterator(target.copy()); } public boolean hasNext() { return target.hasNext(); } public Point minimumSize() { return target.minimumSize(); } public Point preferredSize() { return target.preferredSize(); } public PrintPiece next(int width, int height) { // Use a test iterator so we preserve the original iterator PrintIterator iter = target.copy(); PrintPiece result = PaperClips.next(iter, width, height); if (result == null) return result; if (iter.hasNext()) // Failed to layout the whole target in one piece return null; this.target = iter; return result; } }