org.jpedal.objects.acroforms.GUIData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of OpenViewerFX Show documentation
Show all versions of OpenViewerFX Show documentation
An Open Source JavaFX PDF Viewer
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/support/
*
* (C) Copyright 1997-2016 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---------------
* GUIData.java
* ---------------
*/
package org.jpedal.objects.acroforms;
import java.awt.Rectangle;
import java.util.*;
import org.jpedal.external.CustomFormPrint;
import org.jpedal.external.ExternalHandlers;
import org.jpedal.objects.PdfPageData;
import org.jpedal.objects.acroforms.creation.FormFactory;
import org.jpedal.objects.layers.PdfLayerList;
import org.jpedal.objects.raw.FormObject;
import org.jpedal.objects.raw.PdfDictionary;
/**holds all data not specific to Swing/SWT/ULC*/
public abstract class GUIData {
/**
* flag to make forms draw as images, not swing components
*/
protected boolean rasterizeForms;
/** for if we add a popup to the panel, could be used for adding other objects*/
protected boolean forceRedraw;
//allow user to move relative draw position
protected int userX, userY,widestPageNR,widestPageR;
/** the current display view, Display.SINGLE, Display.CONTINOUS etc */
protected int displayView;
public float dpi=72.0f;
protected final Map rawFormData=new HashMap();
/**allow user to set Forms to ignore*/
protected Map componentsToIgnore=new HashMap();
protected int insetW,insetH;
protected PdfPageData pageData;
/**
* local copy needed in rendering
*/
protected int indent;
protected int[] cropOtherY;
/**
* track page scaling
*/
protected float displayScaling;
protected int rotation;
/**
* used to only redraw as needed
*/
protected float lastScaling = -1, oldRotation, oldIndent;
/**
* used for page tracking
*/
protected int startPage, currentPage, endPage;
/**
* used to draw pages offset if not in SINGLE_PAGE mode
*/
protected int[] xReached, yReached;
/** stores the forms in there original order, accessable by page */
protected List[] formsUnordered, formsOrdered;
/**
* array to hold page for each component so we can scan quickly on page change
*/
private int formCount;
protected PdfLayerList layers;
protected FormFactory formFactory;
public void setLayerData(final PdfLayerList layers){
this.layers=layers;
}
public void setRasterizeForms(final boolean inlineForms) {
rasterizeForms = inlineForms;
}
protected void setListForPage(final int page, final List comps, final boolean isSorted){
if(isSorted){
formsOrdered[page] = comps;
}else{
formsUnordered[page] = comps;
}
}
protected Object checkGUIObjectResolved(final FormObject formObject){
Object comp=null;
if(formObject!=null){
comp= formObject.getGUIComponent();
}
if(formObject!=null && comp==null){
comp= resolveGUIComponent(formObject);
if(comp!=null){
setGUIComp(formObject, comp);
}
}
return comp;
}
protected Object resolveGUIComponent(final FormObject formObject) {
Object retComponent=null;
final int subtype=formObject.getParameterConstant(PdfDictionary.Subtype);
final int formType=formObject.getNameAsConstant(PdfDictionary.FT);//FT
final int formFactoryType=formFactory.getType();
//ExternalHandlers.isXFAPresent() will only be true in forms version of PDF2HTML
if(!ExternalHandlers.isXFAPresent() && (formFactoryType==FormFactory.HTML || formFactoryType==FormFactory.SVG)){
if(subtype!=PdfDictionary.Widget && AcroRenderer.isAnnotation(formObject)){
retComponent = formFactory.annotationButton(formObject);
}
}else if(formType==-1){
retComponent = formFactory.annotationButton(formObject);
} else {
retComponent = getFormComponent(formObject, formType, retComponent);
}
if (retComponent != null) {
formObject.setGUIComponent(retComponent,formFactory.getType());
setGUIComp(formObject, retComponent);
}
return retComponent;
}
private Object getFormComponent(final FormObject formObject, final int formType, Object retComponent) {
final boolean[] flags = formObject.getFieldFlags();//Ff
switch (formType) {
case PdfDictionary.Btn:
boolean isPushButton = false, isRadio = false;// hasNoToggleToOff = false, radioinUnison = false;
if (flags != null) {
isPushButton = flags[FormObject.PUSHBUTTON_ID];
isRadio = flags[FormObject.RADIO_ID];
}
if (isPushButton) {
retComponent = formFactory.pushBut(formObject);
}else if(isRadio){
retComponent = formFactory.radioBut(formObject);
}else {
retComponent = formFactory.checkBoxBut(formObject);
}
break;
case PdfDictionary.Tx:
boolean isMultiline = false, hasPassword = false;// doNotScroll = false, richtext = false, fileSelect = false, doNotSpellCheck = false;
if (flags != null) {
isMultiline = flags[FormObject.MULTILINE_ID] || (formObject.getTextString()!=null && formObject.getTextString().indexOf('\n')!=-1);
hasPassword = flags[FormObject.PASSWORD_ID];
}
if (isMultiline) {
if (hasPassword) {
retComponent = formFactory.multiLinePassword(formObject);
} else {
retComponent = formFactory.multiLineText(formObject);
}
} else {//singleLine
if (hasPassword) {
retComponent = formFactory.singleLinePassword(formObject);
} else {
retComponent = formFactory.singleLineText(formObject);
}
}
break;
case PdfDictionary.Ch:
boolean isCombo = false;// multiSelect = false, sort = false, isEditable = false, doNotSpellCheck = false, comminOnSelChange = false;
if (flags != null) {
isCombo = flags[FormObject.COMBO_ID];
}
if (isCombo) {// || (type==XFAFORM && ((XFAFormObject)formObject).choiceShown!=XFAFormObject.CHOICE_ALWAYS)){
retComponent = formFactory.comboBox(formObject);
} else {//it is a list
retComponent = formFactory.listField(formObject);
}
break;
case PdfDictionary.Sig:
retComponent = formFactory.signature(formObject);
break;
}
return retComponent;
}
public void dispose(){
//Nothing to dispose of in generic method, overrode by swing version
}
protected abstract void displayComponent( final FormObject formObject, final Object comp);
/**
* put components onto screen display
* @param startPage
* @param endPage
*/
protected void displayComponents(final int startPage, final int endPage) {
if (rasterizeForms || formsOrdered==null) {
return;
}
this.startPage = startPage;
this.endPage=endPage;
FormObject formObject;
Object comp;
//System.out.println("displayComponents "+startPage+" "+endPage+" "+SwingUtilities.isEventDispatchThread());
if(startPage>1) {
removeHiddenForms(1, startPage);
}
/*
* forms currently visible
*/
for (int page = startPage; page < endPage; page++) {
//get unsorted components and iterate over forms
if(formsOrdered[page]!=null){
for (final FormObject o : formsOrdered[page]) {
if (o != null) {
formObject = o;
comp= checkGUIObjectResolved(formObject);
if (comp != null) {
displayComponent(formObject, comp);
}
}
}
}
}
removeHiddenForms(endPage,pageData.getPageCount()+1);
}
void removeHiddenForms(final int startPage, final int endPage){
//comment out as could be called by Canoo
//throw new UnsupportedOperationException("Not supported yet.");
}
public boolean hasformsOnPageDecoded(final int page){
return formsOrdered!=null && formsOrdered.length>page && formsOrdered[page]!=null;
}
/**
* setup values needed for drawing page
* @param pageData
* @param page
*/
protected void initParametersForPage(final PdfPageData pageData, final int page, final FormFactory formFactory, final float dpi){
//ensure setup
if(cropOtherY==null || cropOtherY.length<=page) {
this.resetComponents(0, pageData.getPageCount(), false);
}
final int mediaHeight = pageData.getMediaBoxHeight(page);
final int cropTop = (pageData.getCropBoxHeight(page) + pageData.getCropBoxY(page));
//take into account crop
if (mediaHeight != cropTop) {
cropOtherY[page] = (mediaHeight - cropTop);
} else {
cropOtherY[page] = 0;
}
this.currentPage = page; //track page displayed
this.formFactory = formFactory;
this.dpi=dpi;
}
/**
* used to flush/resize data structures on new document/page
* @param formCount
* @param pageCount
* @param keepValues
* return true if successful, false if formCount is less than current count.
*/
public void resetComponents(final int formCount, final int pageCount, final boolean keepValues) {
if(keepValues && this.formCount>formCount) {
return;
}
this.formCount=formCount;
if(!keepValues){
if(formsUnordered==null){
formsUnordered = new List[pageCount+1];
formsOrdered = new List[pageCount + 1];
}
//reset offsets
cropOtherY=new int[pageCount+1];
//reset the multi page shifting values so we dont get forms half way across the page on a single page view.
xReached = yReached = null;
}
}
/**
* pass in current values used for all components
* @param scaling
* @param rotation
* @param indent
*/
public void setPageValues(final float scaling, final int rotation, final int indent, final int userX, final int userY, final int displayView, final int widestPageNR, final int widestPageR) {
this.rotation=rotation;
this.displayScaling=scaling;
this.indent=indent;
this.userX=userX;
this.userY=userY;
this.displayView = displayView;
this.widestPageNR = widestPageNR;
this.widestPageR = widestPageR;
}
/**
* used to pass in offsets and PdfPageData object so we can access in rendering
* @param pageData
* @param insetW
* @param insetH
*/
protected void setPageData(final PdfPageData pageData, final int insetW, final int insetH) {
//track inset on page
this.insetW = insetW;
this.insetH = insetH;
this.pageData = pageData;
}
/**
* offsets for forms in multi-page mode
*/
public void setPageDisplacements(final int[] xReached, final int[] yReached) {
this.xReached = xReached;
this.yReached = yReached;
//force redraw
forceRedraw=true;
}
/**
* force redraw (ie for refreshing layers)
*/
public void setForceRedraw(final boolean forceRedraw) {
this.forceRedraw=forceRedraw;
}
/**
* store form data and allow lookup by PDF ref or name
* (name may not be unique)
* @param formObject
*/
protected void storeRawData(final FormObject formObject) {
final String ref=formObject.getObjectRefAsString();
rawFormData.put(ref,formObject);
}
protected void flushFormData() {
rawFormData.clear();
formsOrdered=null;
formsUnordered=null;
this.oldIndent=-oldIndent;
}
/**
* returns the raw formdata so that DefaultAcroRender can access
*/
protected Map getRawFormData() {
return Collections.unmodifiableMap(rawFormData);
}
protected abstract void setGUIComp(final FormObject formObject, final Object rawField);
/**
* Allow you to get a list of values from the Forms.
*
* If possible we recommend you work with the Form Objects rather than
* resolve GUI components unless you need the GUI values
*
* null key will return all values
*
* if pageNumber is -1 it will process whole document, otherwise just that page
*
* NO values will return empty list, not null
*/
public List getFormComponents(final String key, final ReturnValues value, final int pageNumber) {
final Iterator i=rawFormData.keySet().iterator();
final ArrayList