diff options
Diffstat (limited to 'trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites')
3 files changed, 399 insertions, 289 deletions
diff --git a/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PDFViewerComposite.java b/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PDFViewerComposite.java deleted file mode 100644 index f2852fcc..00000000 --- a/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PDFViewerComposite.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://joinup.ec.europa.eu/software/page/eupl - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - */ -package at.asit.pdfover.gui.composites; - -// Imports -import java.awt.Canvas; -import java.awt.Dimension; -import java.awt.Frame; -import java.awt.Graphics; -import java.awt.geom.Rectangle2D; -import java.io.File; -import java.io.IOException; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.awt.SWT_AWT; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.widgets.Composite; -import org.icepdf.core.exceptions.PDFException; -import org.icepdf.core.exceptions.PDFSecurityException; -import org.icepdf.core.pobjects.Document; -import org.icepdf.core.pobjects.Page; -import org.icepdf.core.util.GraphicsRenderingHints; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.asit.pdfover.gui.workflow.states.PositioningState; - -/** - * Displays a PDF document - */ -public class PDFViewerComposite extends Composite { - /** - * SFL4J Logger instance - **/ - private static final Logger log = LoggerFactory - .getLogger(PDFViewerComposite.class); - - /** - * PDF document - */ - protected Document document; - - /** - * Currently selected page in the document - */ - protected int page; - - /** - * AWT Canvas displaying the document - */ - private Canvas canvas = null; - - /** - * Dimension of each page at default zoom - */ - Dimension[] base_dimensions; - - /** - * Set the document to be displayed - * @param document PDF document to be displayed - * @throws PDFException Error parsing PDF document - * @throws PDFSecurityException Error decrypting PDF document (not supported) - * @throws IOException I/O Error - */ - public void setDocument(File document) throws PDFException, PDFSecurityException, IOException { - this.document = new Document(); - this.document.setFile(document.getPath()); - int pages = this.document.getNumberOfPages(); - - this.base_dimensions = new Dimension[pages]; - for (int page = 0; page < pages; ++page) - this.base_dimensions[page] = this.document.getPageDimension(page, 0f, 1.0f).toDimension(); - - this.page = pages - 1; - - if (this.canvas != null) - this.canvas.repaint(); - } - - /** - * Get the currently selected page in the document - * @return current page - */ - public int getPage() { - return this.page; - } - - /** - * Set the visible page in the document - * @param page new active page - */ - public void setPage(int page) { - this.page = page; - this.canvas.repaint(); - } - - /** - * Create the PDF Viewer composite. - * Displays a PDF document. - * Starts on the last page. - * @param parent parent Composite - * @param style - * @param document - * @throws PDFException Error parsing PDF document - * @throws PDFSecurityException Error decrypting PDF document (not supported) - * @throws IOException I/O Error - */ - public PDFViewerComposite(Composite parent, int style, File document) throws PDFException, PDFSecurityException, IOException { - super(parent, style); - - setDocument(document); - - Frame frame = SWT_AWT.new_Frame(this); - this.canvas = new Canvas() { - private static final long serialVersionUID = 1L; - - @Override - public void paint(Graphics g) { - if (g == null || g.getClip() == null) - return; - int page = getPage(); - // Make page always fit to window - Dimension d = getSize(); - double h_zoom = d.getWidth() / PDFViewerComposite.this.base_dimensions[page].width; - double v_zoom = d.getHeight() / PDFViewerComposite.this.base_dimensions[page].height; - float zoom = (float) (h_zoom < v_zoom ? h_zoom : v_zoom); - if (v_zoom < h_zoom) - { - // Page is narrower than window, center it - g.translate((int) ((d.width - (PDFViewerComposite.this.base_dimensions[page].width * zoom)) / 2), 0); - } - - log.debug("Repainting " + g.getClipBounds().width + "x" + g.getClipBounds().height + " - " + d.width + "x" + d.height); - PDFViewerComposite.this.document.paintPage(page, g, GraphicsRenderingHints.SCREEN, Page.BOUNDARY_CROPBOX, 0f, zoom); - } - }; - frame.add(this.canvas); - frame.pack(); - frame.setVisible(true); - - this.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - int page = getPage(); - int old_page = page; - - switch (e.keyCode) - { - case SWT.PAGE_DOWN: - if (page < (PDFViewerComposite.this.document.getNumberOfPages() - 1)) - ++page; - break; - - case SWT.PAGE_UP: - if (page > 0) - --page; - break; - - case SWT.END: - page = (PDFViewerComposite.this.document.getNumberOfPages() - 1); - break; - - case SWT.HOME: - page = 0; - break; - } - - if (page != old_page) - setPage(page); - } - }); - } -} diff --git a/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PositioningComposite.java b/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PositioningComposite.java index f1f89d79..d1309cf9 100644 --- a/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PositioningComposite.java +++ b/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/PositioningComposite.java @@ -16,32 +16,30 @@ package at.asit.pdfover.gui.composites; // Imports +import java.awt.Frame; +import java.awt.Image; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; import java.io.File; import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DragDetectEvent; -import org.eclipse.swt.events.DragDetectListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.awt.SWT_AWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.icepdf.core.exceptions.PDFException; -import org.icepdf.core.exceptions.PDFSecurityException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.asit.pdfover.gui.workflow.states.State; import at.asit.pdfover.signator.SignaturePosition; +import com.sun.pdfview.PDFFile; + /** * * @@ -53,55 +51,40 @@ public class PositioningComposite extends StateComposite { static final Logger log = LoggerFactory .getLogger(PositioningComposite.class); - PDFViewerComposite viewer = null; + private SignaturePanel viewer = null; - Canvas signature = null; + private PDFFile pdf = null; - private SignaturePosition position = null; + private Frame frame = null; - boolean doDrag = false; + int currentPage; - Point origMousePos = null; - Rectangle origSigPos = null; + int numPages; - /** - * Gets the position of the signature - * @return the SignaturePosition - */ - public SignaturePosition getPosition() { - return this.position; - } - - /** - * Sets the position - * @param position - */ - public void setPosition(SignaturePosition position) { - this.position = position; - } + private SignaturePosition position = null; /** * Set the PDF Document to display * @param document document to display - * @throws PDFException Error parsing PDF document - * @throws PDFSecurityException Error decrypting PDF document (not supported) * @throws IOException I/O Error */ - public void displayDocument(File document) throws PDFException, PDFSecurityException, IOException { + public void displayDocument(File document) throws IOException { + RandomAccessFile rafile = new RandomAccessFile(document, "r"); //$NON-NLS-1$ + FileChannel chan = rafile.getChannel(); + ByteBuffer buf = chan.map(FileChannel.MapMode.READ_ONLY, 0, chan.size()); + chan.close(); + rafile.close(); + + this.pdf = new PDFFile(buf); if (this.viewer == null) { - this.viewer = new PDFViewerComposite(this, SWT.EMBEDDED | SWT.NO_BACKGROUND, document); - resizeViewer(); + this.viewer = new SignaturePanel(this.pdf); + this.frame.add(this.viewer); } else - this.viewer.setDocument(document); - } - - void resizeViewer() - { - Rectangle clientArea = this.getClientArea(); - log.debug("Resizing to " + clientArea.width + "x" + clientArea.height); - this.viewer.setBounds(0, 0, clientArea.width, clientArea.height); + this.viewer.setDocument(this.pdf); + this.numPages = this.pdf.getNumPages(); + showPage(this.numPages); } /** @@ -111,62 +94,73 @@ public class PositioningComposite extends StateComposite { * @param state */ public PositioningComposite(Composite parent, int style, State state) { - super(parent, style, state); - this.setLayout(null); - - this.addListener(SWT.Resize, new Listener() { - @Override - public void handleEvent(Event e) { - if (PositioningComposite.this.viewer != null) - resizeViewer(); - } - }); - - this.signature = new Canvas(this, SWT.NO_BACKGROUND); - this.signature.setBounds(200, 200, 150, 40); - this.signature.addPaintListener(new PaintListener() { - @Override - public void paintControl(PaintEvent e) { -// PositioningComposite.this.viewer.redraw(); - Rectangle r = ((Canvas) e.widget).getBounds(); - e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLUE)); - e.gc.drawFocus(5, 5, r.width - 10, r.height - 10); - e.gc.drawText("Position Signature", 10, 10); - } - }); - this.signature.addDragDetectListener(new DragDetectListener() { - @Override - public void dragDetected(DragDetectEvent e) { - PositioningComposite.this.doDrag = true; - origMousePos = Display.getCurrent().getCursorLocation(); - origSigPos = ((Canvas) e.widget).getBounds(); + super(parent, style | SWT.EMBEDDED, state); + //this.setLayout(null); + this.frame = SWT_AWT.new_Frame(this); + this.addKeyListener(this.keyListener); + this.frame.addMouseWheelListener(this.mouseListener); + } + + private KeyListener keyListener = new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + int newPage = PositioningComposite.this.currentPage; + + switch (e.keyCode) + { + case SWT.PAGE_DOWN: + if (PositioningComposite.this.currentPage < PositioningComposite.this.numPages) + ++newPage; + break; + + case SWT.PAGE_UP: + if (PositioningComposite.this.currentPage > 1) + --newPage; + break; + + case SWT.END: + newPage = PositioningComposite.this.numPages; + break; + + case SWT.HOME: + newPage = 1; + break; + + case SWT.CR: + case SWT.KEYPAD_CR: + PositioningComposite.this.setFinalPosition(); + break; } - }); - this.signature.addMouseMoveListener(new MouseMoveListener() { - @Override - public void mouseMove(MouseEvent e) { - if (PositioningComposite.this.doDrag) - { - Point newMousePos = Display.getCurrent().getCursorLocation(); - int x = origSigPos.x + (newMousePos.x - origMousePos.x); - int y = origSigPos.y + (newMousePos.y - origMousePos.y); - PositioningComposite.this.signature.setBounds(x, y, origSigPos.width, origSigPos.height); - } + + if (newPage != PositioningComposite.this.currentPage) + showPage(newPage); + } + }; + + private MouseWheelListener mouseListener = new MouseWheelListener() { + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + int newPage = PositioningComposite.this.currentPage; + + if (e.getUnitsToScroll() < 0) + { + if (PositioningComposite.this.currentPage > 1) + newPage--; } - }); - this.signature.addMouseListener(new MouseAdapter() { - @Override - public void mouseUp(MouseEvent e) { - if (PositioningComposite.this.doDrag) - { - PositioningComposite.this.doDrag = false; - return; - } - // TODO: FIX to get real position - PositioningComposite.this.setPosition(new SignaturePosition()); // Setting auto position for testing - PositioningComposite.this.state.updateStateMachine(); + else if (e.getUnitsToScroll() > 0) + { + if (PositioningComposite.this.currentPage < PositioningComposite.this.numPages) + newPage++; } - }); + + if (newPage != PositioningComposite.this.currentPage) + showPage(newPage); + } + }; + + void showPage(int page) { + this.currentPage = page; + this.viewer.showPage(page); } @Override @@ -181,4 +175,22 @@ public class PositioningComposite extends StateComposite { public void doLayout() { this.layout(true, true); } + + /** + * Set the signature position and continue to the next state + * @param position the signature position + */ + void setFinalPosition() { + // TODO: check if this is the real position + this.position = new SignaturePosition(this.viewer.getSignaturePositionX(), this.viewer.getSignaturePositionY()); + PositioningComposite.this.state.updateStateMachine(); + } + + /** + * Get the signature position + * @return the signature position + */ + public SignaturePosition getPosition() { + return this.position; + } } diff --git a/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java b/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java new file mode 100644 index 00000000..f90b2591 --- /dev/null +++ b/trunk/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/SignaturePanel.java @@ -0,0 +1,285 @@ +/* + * Copyright 2012 by A-SIT, Secure Information Technology Center Austria + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + */ +package at.asit.pdfover.gui.composites; + +// Imports +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Point2D; + +import javax.swing.JPanel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.pdfview.PDFFile; +import com.sun.pdfview.PDFPage; + +/** + * + */ +public class SignaturePanel extends JPanel { + /** + * SLF4J Logger instance + **/ + private static final Logger log = LoggerFactory + .getLogger(SignaturePanel.class); + + /** Default serial version ID */ + private static final long serialVersionUID = 1L; + + /** The PDF file being displayed */ + private PDFFile pdf; + /** The image of the rendered PDF page being displayed */ + Image currentImage; + /** The current PDFPage that was rendered into currentImage */ + private PDFPage currentPage; + /** The current page number */ + AffineTransform currentXform; + /** The horizontal offset of the image from the left edge of the panel */ + int offx; + /** The vertical offset of the image from the top of the panel */ + int offy; + /** The size of the image */ + private Dimension prevSize; + /** The position of the signature, in document space */ + Point2D sigPagePos; + /** The position of the signature, in screen space */ + Point2D sigScreenPos; + + /** + * Create a new PagePanel, with a default size of 800 by 600 pixels. + * @param pdf the PDFFile to display + */ + public SignaturePanel(PDFFile pdf) { + super(new BorderLayout()); + this.pdf = pdf; + this.sigPagePos = null; + setPreferredSize(new Dimension(800, 600)); + setFocusable(true); + addMouseListener(this.mouseListener); + addMouseMotionListener(this.mouseListener); + } + + /** + * Set a new document to be displayed + * @param pdf the PDFFile to be displayed + */ + public void setDocument(PDFFile pdf) + { + this.pdf = pdf; + this.sigPagePos = null; + showPage(pdf.getNumPages()); + } + + /** + * Change the currently displayed page + * @param page the number of the page to display + */ + public void showPage(int page) { + //sigPagePos = null; + showPage(this.pdf.getPage(page)); + } + + /** + * Get the current horizontal position of the signature + * @return signature x coordinate + */ + public float getSignaturePositionX() { + return (float) this.sigPagePos.getX(); + } + + /** + * Get the current vertical position of the signature + * @return signature y coordinate + */ + public float getSignaturePositionY() { + return (float) this.sigPagePos.getY(); + } + + /** + * Stop the generation of any previous page, and draw the new one. + * + * @param page the PDFPage to draw. + */ + private synchronized void showPage(PDFPage page) { + // stop drawing the previous page + if (this.currentPage != null && this.prevSize != null) { + this.currentPage.stop(this.prevSize.width, this.prevSize.height, null); + } + + // set up the new page + this.currentPage = page; + + if (this.currentPage == null) { + // no page + this.currentImage = null; + this.currentXform = null; + repaint(); + } else { + // start drawing + Dimension sz = getSize(); + if (sz.width + sz.height == 0) { + // no image to draw. + return; + } + + Dimension pageSize = this.currentPage.getUnstretchedSize(sz.width, sz.height, + null); + + // get the new image + this.currentImage = this.currentPage.getImage(pageSize.width, pageSize.height, + null, this); + + // calculate the transform from page to screen space + this.currentXform = this.currentPage.getInitialTransform(pageSize.width, + pageSize.height, null); + + if (this.sigPagePos != null) + this.sigScreenPos = this.currentXform.transform(this.sigPagePos, this.sigScreenPos); + + // invert the transform (screen to page space) + try { + this.currentXform = this.currentXform.createInverse(); + } catch (NoninvertibleTransformException nte) { + log.error("Error inverting page transform!", nte); + } + + if (this.sigPagePos == null) + { + this.sigScreenPos = new Point2D.Double((pageSize.getWidth() / 3) * 2, (pageSize.getHeight() / 4) * 3); + this.sigPagePos = this.currentXform.transform(this.sigScreenPos, this.sigPagePos); + } + + this.prevSize = pageSize; + + repaint(); + } + } + + /** + * Draw the image. + */ + @Override + public void paint(Graphics g) { + Dimension sz = getSize(); + g.setColor(getBackground()); + g.fillRect(0, 0, getWidth(), getHeight()); + if (this.currentImage == null) { + g.setColor(Color.black); + g.drawString("No page selected", getWidth() / 2 - 30, + getHeight() / 2); + if (this.currentPage != null) { + showPage(this.currentPage); + } + } else { + // draw the image + int imwid = this.currentImage.getWidth(null); + int imhgt = this.currentImage.getHeight(null); + + // draw it centered within the panel + this.offx = (sz.width - imwid) / 2; + this.offy = (sz.height - imhgt) / 2; + + if ((imwid == sz.width && imhgt <= sz.height) + || (imhgt == sz.height && imwid <= sz.width)) { + + g.drawImage(this.currentImage, this.offx, this.offy, this); + + g.setColor(Color.red); + int sigx = (int) (this.offx + this.sigScreenPos.getX()); + int sigy = (int) (this.offy + this.sigScreenPos.getY()); + g.drawRect(sigx - 10, sigy - 10, 20, 20); + + } else { + // the image is bogus. try again, or give up. + if (this.currentPage != null) { + showPage(this.currentPage); + } + g.setColor(Color.black); + g.drawString("Could not render page", getWidth() / 2 - 30, + getHeight() / 2); + } + } + } + + /** + * Handles notification of the fact that some part of the image changed. + * Repaints that portion. + * + * @return true if more updates are desired. + */ + @Override + public boolean imageUpdate(Image img, int infoflags, int x, int y, + int width, int height) { + if ((infoflags & (SOMEBITS | ALLBITS)) != 0) { + repaint(x + this.offx, y + this.offy, width, height); + } + return ((infoflags & (ALLBITS | ERROR | ABORT)) == 0); + } + + private MouseAdapter mouseListener = new MouseAdapter() { + + private void updateSigPos(int sigx, int sigy) { + if (SignaturePanel.this.currentImage == null) + return; + sigx -= SignaturePanel.this.offx; + sigx = clamp(sigx, 0, SignaturePanel.this.currentImage.getWidth(null)); + sigy -= SignaturePanel.this.offy; + sigy = clamp(sigy, 0, SignaturePanel.this.currentImage.getHeight(null)); + SignaturePanel.this.sigScreenPos = new Point2D.Double(sigx, sigy); + SignaturePanel.this.sigPagePos = SignaturePanel.this.currentXform.transform(SignaturePanel.this.sigScreenPos, SignaturePanel.this.sigPagePos); + repaint(); + } + + /** Handles a mousePressed event */ + @Override + public void mousePressed(MouseEvent evt) { + updateSigPos(evt.getX(), evt.getY()); + } + + /** + * Handles a mouseDragged event. + */ + @Override + public void mouseDragged(MouseEvent evt) { + updateSigPos(evt.getX(), evt.getY()); + } + }; + + /** + * Clamp x to be within [min-max] + * @param x int to clamp + * @param min minimum value + * @param max maximum value + * @return clamped x + */ + static int clamp(int x, int min, int max) + { + if (x < min) + x = min; + else if (x > max) + x = max; + return x; + } +} |