All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.icepdf.ri.common.tools.HighLightAnnotationHandler Maven / Gradle / Ivy

There is a newer version: 6.2.2
Show newest version
/*
 * Copyright 2006-2016 ICEsoft Technologies Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS
 * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.icepdf.ri.common.tools;

import org.icepdf.core.pobjects.Name;
import org.icepdf.core.pobjects.PDate;
import org.icepdf.core.pobjects.Page;
import org.icepdf.core.pobjects.annotations.Annotation;
import org.icepdf.core.pobjects.annotations.AnnotationFactory;
import org.icepdf.core.pobjects.annotations.TextMarkupAnnotation;
import org.icepdf.core.pobjects.graphics.text.GlyphText;
import org.icepdf.core.pobjects.graphics.text.LineText;
import org.icepdf.core.pobjects.graphics.text.PageText;
import org.icepdf.core.pobjects.graphics.text.WordText;
import org.icepdf.core.util.Defs;
import org.icepdf.ri.common.views.AbstractPageViewComponent;
import org.icepdf.ri.common.views.AnnotationCallback;
import org.icepdf.ri.common.views.DocumentViewController;
import org.icepdf.ri.common.views.DocumentViewModel;
import org.icepdf.ri.common.views.annotations.AbstractAnnotationComponent;
import org.icepdf.ri.common.views.annotations.AnnotationComponentFactory;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.NoninvertibleTransformException;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;

/**
 * HighLightAnnotationHandler tool extends TextSelectionPageHandler which
 * takes care visually selected text as the mouse is dragged across text on the
 * current page.
 * 

* Once the mouseReleased event is fired this handler will create new * HighLightAnnotation and respective AnnotationComponent. The addition of the * Annotation object to the page is handled by the annotation callback. Once * create the handler will deselect the text and the newly created annotation * will be displayed. * * @since 5.0 */ public class HighLightAnnotationHandler extends TextSelectionPageHandler { /** * Property when enabled will set the /contents key value to the selected text of the markup annotation. */ private static boolean enableHighlightContents; static { try { enableHighlightContents = Defs.booleanProperty( "org.icepdf.core.views.page.annotation.highlightContent.enabled", false); } catch (NumberFormatException e) { logger.warning("Error reading highlight selection content enabled property."); } } protected Name highLightType; public HighLightAnnotationHandler(DocumentViewController documentViewController, AbstractPageViewComponent pageViewComponent, DocumentViewModel documentViewModel) { super(documentViewController, pageViewComponent, documentViewModel); // default type highLightType = Annotation.SUBTYPE_HIGHLIGHT; } /** * Override the base functionality as we don't want to support double and * triple click work selection for highlights. * * @param e mouse event */ public void mouseClicked(MouseEvent e) { if (pageViewComponent != null) { pageViewComponent.requestFocus(); } } /** * Invoked when a mouse button has been released on a component. */ public void mouseReleased(MouseEvent e) { // get the selection bounds ArrayList highlightBounds = getSelectedTextBounds(); // clear the selection super.mouseReleased(e); // create the text markup annotation. createTextMarkupAnnotation(highlightBounds); // set the annotation tool to he select tool // documentViewController.getParentController().setDocumentToolMode( // DocumentViewModel.DISPLAY_TOOL_SELECTION); } public void createTextMarkupAnnotation(ArrayList highlightBounds) { // mke sure we don't create a highlight annotation for every word in the // document when first selecting the tool for highlighted next. . if (documentViewModel.isSelectAll()) { documentViewController.clearSelectedText(); } // get the geometric path of the selected text if (highlightBounds == null) { highlightBounds = getSelectedTextBounds(); } // grab the selected text String contents = enableHighlightContents && highlightBounds != null ? getSelectedText() : ""; // clear the selected text documentViewController.clearSelectedText(); if (highlightBounds != null) { // bound of the selected text GeneralPath highlightPath = new GeneralPath(); for (Shape bounds : highlightBounds) { highlightPath.append(bounds, false); } // get the bounds before convert to page space Rectangle bounds = highlightPath.getBounds(); Rectangle tBbox = convertToPageSpace(highlightBounds, highlightPath); // create annotations types that that are rectangle based; // which is actually just link annotations TextMarkupAnnotation annotation = (TextMarkupAnnotation) AnnotationFactory.buildAnnotation( documentViewModel.getDocument().getPageTree().getLibrary(), highLightType, tBbox); // pass outline shapes and bounds to create the highlight shapes annotation.setContents(contents != null && enableHighlightContents ? contents : highLightType.toString()); annotation.setColor(annotation.getTextMarkupColor()); annotation.setCreationDate(PDate.formatDateTime(new Date())); annotation.setTitleText(System.getProperty("user.name")); annotation.setMarkupBounds(highlightBounds); annotation.setMarkupPath(highlightPath); annotation.setBBox(tBbox); // finalized the appearance properties. annotation.resetAppearanceStream(getPageTransform()); // create new annotation given the general path AbstractAnnotationComponent comp = AnnotationComponentFactory.buildAnnotationComponent( annotation, documentViewController, pageViewComponent, documentViewModel); // convert to user rect to page space along with the bounds. comp.setBounds(bounds); comp.refreshAnnotationRect(); // create component and add it to the page. // add them to the container, using absolute positioning. if (documentViewController.getAnnotationCallback() != null) { AnnotationCallback annotationCallback = documentViewController.getAnnotationCallback(); annotationCallback.newAnnotation(pageViewComponent, comp); } } pageViewComponent.repaint(); } private String getSelectedText() { Page currentPage = pageViewComponent.getPage(); return currentPage.getViewText().getSelected().toString(); } private ArrayList getSelectedTextBounds() { Page currentPage = pageViewComponent.getPage(); ArrayList highlightBounds = null; if (currentPage != null && currentPage.isInitiated()) { PageText pageText = currentPage.getViewText(); if (pageText != null) { // get page transformation AffineTransform pageTransform = currentPage.getPageTransform( documentViewModel.getPageBoundary(), documentViewModel.getViewRotation(), documentViewModel.getViewZoom()); // paint the sprites GeneralPath textPath; ArrayList pageLines = pageText.getPageLines(); if (pageLines != null) { for (LineText lineText : pageLines) { java.util.List words = lineText.getWords(); if (words != null) { for (WordText wordText : words) { // paint whole word if (wordText.isSelected() || wordText.isHighlighted()) { textPath = new GeneralPath(wordText.getBounds()); textPath.transform(pageTransform); // paint highlight over any selected if (wordText.isSelected()) { if (highlightBounds == null) { highlightBounds = new ArrayList(); } highlightBounds.add(textPath.getBounds2D()); } } // check children else { for (GlyphText glyph : wordText.getGlyphs()) { if (glyph.isSelected()) { textPath = new GeneralPath(glyph.getBounds()); textPath.transform(pageTransform); if (highlightBounds == null) { highlightBounds = new ArrayList(); } highlightBounds.add(textPath.getBounds2D()); } } } } } } } } } return highlightBounds; } /** * Convert the shapes that make up the annotation to page space so that * they will scale correctly at different zooms. * * @return transformed bBox. */ protected Rectangle convertToPageSpace(ArrayList bounds, GeneralPath path) { Page currentPage = pageViewComponent.getPage(); AffineTransform at = currentPage.getPageTransform( documentViewModel.getPageBoundary(), documentViewModel.getViewRotation(), documentViewModel.getViewZoom()); try { at = at.createInverse(); } catch (NoninvertibleTransformException e) { logger.log(Level.FINE, "Error converting to page space.", e); } // convert the two points as well as the bbox. Rectangle tBbox = at.createTransformedShape(path).getBounds(); // convert the points Shape bound; for (int i = 0; i < bounds.size(); i++) { bound = bounds.get(i); bound = at.createTransformedShape(bound); bounds.set(i, bound); // bound.setRect(tBound.getX(), tBound.getY(), // tBound.getWidth(), tBound.getHeight()); } path.transform(at); return tBbox; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy