org.jpedal.objects.acroforms.actions.EmptyActionHandler Maven / Gradle / Ivy
Show all versions of OpenViewerFX Show documentation
/*
* ===========================================
* 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-2017 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
@LICENSE@
*
* ---------------
* EmptyActionHandler.java
* ---------------
*/
package org.jpedal.objects.acroforms.actions;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
import org.jpedal.PdfDecoderInt;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.Javascript;
import org.jpedal.objects.acroforms.AcroRenderer;
import org.jpedal.objects.acroforms.ReturnValues;
import org.jpedal.objects.acroforms.actions.privateclasses.FieldsHideObject;
import org.jpedal.objects.layers.PdfLayerList;
import org.jpedal.objects.raw.*;
import org.jpedal.utils.LogWriter;
public class EmptyActionHandler implements ActionHandler {
protected static final boolean showMethods = false;
protected PdfObjectReader currentPdfFile;
protected Javascript javascript;
protected AcroRenderer acrorend;
//handle so we can access
protected PdfDecoderInt decode_pdf;
@Override
public void init(final PdfDecoderInt decode_pdf, final Javascript javascript, final AcroRenderer acrorend) {
if (showMethods) {
System.out.println("DefaultActionHandler.init()");
}
if (decode_pdf != null) {
currentPdfFile = decode_pdf.getIO();
}
this.javascript = javascript;
this.acrorend = acrorend;
this.decode_pdf = decode_pdf;
}
@Override
public Object setHoverCursor() {
return new MouseListener() {
@Override
public void mouseEntered(final MouseEvent e) {
}
@Override
public void mouseExited(final MouseEvent e) {
}
@Override
public void mouseClicked(final MouseEvent e) {
}
@Override
public void mousePressed(final MouseEvent e) {
}
@Override
public void mouseReleased(final MouseEvent e) {
}
};
}
/**
* A action when pressed in active area ?some others should now be ignored?
*/
@Override
public void A(final Object raw, FormObject formObj, final int eventType) {
if (showMethods) {
System.out.println("DefaultActionHandler.A() ");
}
switch (eventType) {
case MOUSEENTERED:
javascript.execute(formObj, PdfDictionary.E, ActionHandler.TODO, ' ');
break;
case MOUSEEXITED:
javascript.execute(formObj, PdfDictionary.X, ActionHandler.TODO, ' ');
break;
case MOUSEPRESSED:
javascript.execute(formObj, PdfDictionary.D, ActionHandler.TODO, ' ');
break;
case MOUSERELEASED:
javascript.execute(formObj, PdfDictionary.A, ActionHandler.TODO, ' ');
javascript.execute(formObj, PdfDictionary.U, ActionHandler.TODO, ' ');
break;
default:
break;
}
// new version
PdfObject aData = null;
if (eventType == MOUSERELEASED) {
//get the A action if we have activated the form (released)
aData = formObj.getDictionary(PdfDictionary.A);
}
if (aData == null) {
aData = formObj.getDictionary(PdfDictionary.AA);
if (aData != null) {
switch (eventType) {
case MOUSEENTERED:
aData = aData.getDictionary(PdfDictionary.E);
break;
case MOUSEEXITED:
aData = aData.getDictionary(PdfDictionary.X);
break;
case MOUSEPRESSED:
aData = aData.getDictionary(PdfDictionary.D);
break;
case MOUSERELEASED:
aData = aData.getDictionary(PdfDictionary.U);
break;
default:
break;
}
}
}
gotoDest(formObj, eventType, PdfDictionary.Dest);
final int subtype = formObj.getParameterConstant(PdfDictionary.Subtype);
final int formType = formObj.getNameAsConstant(PdfDictionary.FT);
final int popupFlag = formObj.getActionFlag();
if (formType == PdfDictionary.Sig) {
// additionalAction_Signature(formObj, eventType);
} else if (eventType == MOUSECLICKED && (popupFlag == FormObject.POPUP || subtype == PdfDictionary.Text)) {
// If the form object has an IRT entry and is part of a group, the popup that get's shown
// is the one associated with the IRT object
if (formObj.getDictionary(PdfDictionary.IRT) != null && formObj.getNameAsConstant(PdfDictionary.RT) == PdfDictionary.Group) {
final FormObject IRT = (FormObject) formObj.getDictionary(PdfDictionary.IRT);
currentPdfFile.checkResolved(IRT);
formObj = IRT;
}
popup(raw, formObj, currentPdfFile);
} else {
// can get empty values
if (aData == null) {
return;
}
final int command = aData.getNameAsConstant(PdfDictionary.S);
// S is Name of action
switch (command) {
case PdfDictionary.Named:
additionalAction_Named(aData);
break;
case PdfDictionary.GoTo:
gotoDest(aData, eventType, command);
break;
case PdfDictionary.GoToR:
gotoDest(aData, eventType, command);
break;
case PdfDictionary.ResetForm:
additionalAction_ResetForm(aData);
break;
case PdfDictionary.SubmitForm:
additionalAction_SubmitForm(aData);
break;
case PdfDictionary.JavaScript:
//javascript called above.
break;
case PdfDictionary.Hide:
additionalAction_Hide(aData);
break;
case PdfDictionary.URI:
// additionalAction_URI(aData.getTextStreamValue(PdfDictionary.URI));
break;
case PdfDictionary.Launch:
LogWriter.writeFormLog("{stream} launch activate action NOT IMPLEMENTED", FormStream.debugUnimplemented);
if (FormStream.debugUnimplemented) {
System.out.println("{internal only} launch activate action NOT IMPLEMENTED");
}
break;
case PdfDictionary.SetOCGState:
additionalAction_OCState(eventType, aData);
break;
case PdfDictionary.Sound:
if (eventType == MOUSECLICKED || eventType == MOUSERELEASED) {
additionalAction_Sound(aData);
}
break;
case PdfDictionary.Unknown:
LogWriter.writeFormLog("{stream} Activate Action UNKNOWN command " + aData.getName(PdfDictionary.S) + ' ' + formObj.getObjectRefAsString(), FormStream.debugUnimplemented);
break;
default:
LogWriter.writeFormLog("{stream} UNKNOWN Command " + aData.getName(PdfDictionary.S) + " Action", FormStream.debugUnimplemented);
}
}
}
private void additionalAction_Sound(final PdfObject aData) {
final PdfObject soundObj = aData.getDictionary(PdfDictionary.Sound);
// read now as lazy initialisation
currentPdfFile.checkResolved(soundObj);
try {
int channels = soundObj.getInt(PdfDictionary.C);
if (channels == -1) {
channels = 1;
}
int bitsPerSample = soundObj.getInt(PdfDictionary.B);
if (bitsPerSample == -1) {
bitsPerSample = 8;
}
final float samplingRate = soundObj.getInt(PdfDictionary.R);
int e = soundObj.getNameAsConstant(PdfDictionary.E);
if (e == PdfDictionary.Unknown) {
e = PdfDictionary.Unsigned;
}
SoundHandler.setAudioFormat(e, bitsPerSample, samplingRate, channels);
SoundHandler.PlaySound(soundObj.getDecodedStream());
} catch (final Exception e) {
LogWriter.writeLog("Exception: " + e.getMessage());
}
}
private void additionalAction_OCState(final int eventType, final PdfObject aData) {
if (eventType == MOUSECLICKED) {
final PdfArrayIterator state = aData.getMixedArray(PdfDictionary.State);
if (state != null && state.getTokenCount() > 0) {
final PdfLayerList layers = (PdfLayerList) decode_pdf.getJPedalObject(PdfDictionary.Layer);
final int count = state.getTokenCount();
final int action = state.getNextValueAsConstant(true);
String ref;
for (int jj = 1; jj < count; jj++) {
ref = state.getNextValueAsString(true);
final String layerName = layers.getNameFromRef(ref);
// toggle layer status when clicked
final Runnable updateAComponent = new Runnable() {
@Override
public void run() {
// update settings on display and in PdfDecoder
final boolean newState;
if (action == PdfDictionary.Toggle) {
newState = !layers.isVisible(layerName);
} else {
newState = action != PdfDictionary.OFF;
}
layers.setVisiblity(layerName, newState);
// decode again with new settings
try {
decode_pdf.decodePage(-1);
} catch (final Exception e) {
LogWriter.writeLog("Exception: " + e.getMessage());
}
}
};
SwingUtilities.invokeLater(updateAComponent);
}
}
}
}
private void additionalAction_Named(final PdfObject aData) {
final int name = aData.getNameAsConstant(PdfDictionary.N);
if (name == PdfDictionary.Print) {
// additionalAction_Print(eventType);
} else if (name == PdfDictionary.SaveAs) {
//additionalAction_SaveAs();
} else if (name == PdfDictionary.NextPage) {
changeTo(null, decode_pdf.getlastPageDecoded() + 1, null, null, true);
} else if (name == PdfDictionary.PrevPage) {
changeTo(null, decode_pdf.getlastPageDecoded() - 1, null, null, true);
} else if (name == PdfDictionary.FirstPage) {
changeTo(null, 1, null, null, true);
} else if (name == PdfDictionary.GoBack) {
} else if (name == PdfDictionary.LastPage) {
changeTo(null, decode_pdf.getPageCount(), null, null, true);
} else if (name == PdfDictionary.ZoomTo) {
} else if (name == PdfDictionary.FullScreen) {
} else if (name == PdfDictionary.AcroForm_FormsJSGuide) { //AcroForm:FormsJSGuide
} else if (FormStream.debugUnimplemented) {
System.out.println("{internal only} Named Action NOT IMPLEMENTED " + aData.getName(PdfDictionary.N) + ' ' + decode_pdf.getFileName());
}
}
private void additionalAction_Hide(final PdfObject aData) {
if (showMethods) {
System.out.println("DefaultActionHandler.additionalAction_Hide()");
}
final FieldsHideObject fieldsToHide = new FieldsHideObject();
getHideMap(aData, fieldsToHide);
setFieldVisibility(fieldsToHide);
}
private void additionalAction_SubmitForm(final PdfObject aData) {
if (showMethods) {
System.out.println("DefaultActionHandler.additionalAction_SubmitForm()");
}
boolean newExcludeList = false;
String newSubmitURL = null;
String[] newListOfFields = null;
//get the F dictionary
final PdfObject dict = aData.getDictionary(PdfDictionary.F);
//then get the submit URL to use
if (dict != null) {
newSubmitURL = dict.getTextStreamValue(PdfDictionary.F);
}
//get the fields we need to change
PdfArrayIterator fieldList = aData.getMixedArray(PdfDictionary.Fields);
if (fieldList != null) {
if (fieldList.getTokenCount() < 1) {
fieldList = null;
}
if (fieldList != null) {
// code goes here
final int fieldIndex = 0;
newListOfFields = new String[fieldList.getTokenCount()];
// go through list of fields and store so we can send
String formObject;
String tok, preName = null;
final StringBuilder names = new StringBuilder();
while (fieldList.hasMoreTokens()) {
formObject = fieldList.getNextValueAsString(true);
if (formObject.contains(".x")) {
preName = formObject.substring(formObject.indexOf('.') + 1,
formObject.indexOf(".x") + 1);
}
if (formObject.contains(" R")) {
final FormObject formObj = new FormObject(formObject);
currentPdfFile.readObject(formObj);
tok = formObj.getTextStreamValue(PdfDictionary.T);
if (preName != null) {
names.append(preName);
}
names.append(tok);
names.append(',');
}
}
newListOfFields[fieldIndex] = names.toString();
} // end of code section
} // END of Fields defining
//if there was a list of fields read the corresponding Flags see pdf spec v1.6 p662
if (newListOfFields != null) {
// if list is null we ignore this flag anyway
final int flags = aData.getInt(PdfDictionary.Flags);
if ((flags & 1) == 1) {
// fields is an exclude list
newExcludeList = true;
}
} // END of if exclude list ( Flags )
// send our values to the actioning method
submitURL(newListOfFields, newExcludeList, newSubmitURL);
}
private void additionalAction_ResetForm(final PdfObject aData) {
if (showMethods) {
System.out.println("DefaultActionHandler.additionalAction_ResetForm()");
}
final int flags = aData.getInt(PdfDictionary.Flags); // potential problem: returns -1 for unknown values also
boolean shouldExclude = false;
if ((flags & 1) == 1) {
// fields is an exclude list
shouldExclude = true;
}
final Object[] allFormObjects = acrorend.getFormComponents(null, ReturnValues.FORMOBJECTS_FROM_REF, -1);
// System.out.println("allFormObjects = ");
// for(int i = 0; i < allFormObjects.length; i ++) {
// FormObject formObject = (FormObject) allFormObjects[i];
// System.out.println(formObject.getTextStreamValue(PdfDictionary.T));
// }
final PdfArrayIterator fieldList = aData.getMixedArray(PdfDictionary.Fields);
String[] fields = null;
if (fieldList != null && fieldList.getTokenCount() > 0) {
fields = new String[fieldList.getTokenCount()];
int i = 0;
while (fieldList.hasMoreTokens()) {
final String fieldname = fieldList.getNextValueAsString(true);
fields[i] = fieldname;
i++;
}
}
// System.out.println("should exclude: " + shouldExclude);
// System.out.println("fields = ");
// if(fields != null) {
// for(int i = 0; i < fields.length; i ++) {
// System.out.println(fields[i]);
// }
// }
if (shouldExclude) {
// The Fields entry refers to the fields to exclude from being reset
if (fields != null && fields.length > 0) {
for (final Object allFormObject : allFormObjects) {
final FormObject formObject = (FormObject) allFormObject;
boolean skipForm = false;
for (final String name : fields) {
if (name == null) {
continue;
}
// Check if the names are the same
if (formObject.getTextStreamValue(PdfDictionary.T).equals(name)) {
skipForm = true;
break;
}
}
if (!skipForm) {
// Form not present in fields array
final String defaultValue = formObject.getTextStreamValue(PdfDictionary.DV);
formObject.updateValue(defaultValue, false, true);
// if(formObject.hasKeyArray(PdfDictionary.Kids)) {
// byte[][] kidList = formObject.getKeyArray(PdfDictionary.Kids);
// for (final byte[] aKidList : kidList) { //iterate through all parts
// String key = new String(aKidList);
// Object[] formComps = acrorend.getFormComponents(key, ReturnValues.FORMOBJECTS_FROM_REF, -1);
// for(int y = 0; y < formComps.length; y ++) {
// FormObject childObj = (FormObject) formComps[y];
// String dv = childObj.getTextStreamValue(PdfDictionary.DV);
// childObj.updateValue(dv, false, true);
// }
//
// }
// }
}
}
} else {
// Reset all forms
for (final Object allFormObject : allFormObjects) {
final FormObject formObject = (FormObject) allFormObject;
final String defaultValue = formObject.getTextStreamValue(PdfDictionary.DV);
formObject.updateValue(defaultValue, false, true);
// if(formObject.hasKeyArray(PdfDictionary.Kids)) {
// byte[][] kidList = formObject.getKeyArray(PdfDictionary.Kids);
// for (final byte[] aKidList : kidList) { //iterate through all parts
// String key = new String(aKidList);
// Object[] formComps = acrorend.getFormComponents(key, ReturnValues.FORMOBJECTS_FROM_REF, -1);
// for(int y = 0; y < formComps.length; y ++) {
// FormObject childObj = (FormObject) formComps[y];
// String dv = childObj.getTextStreamValue(PdfDictionary.DV);
// childObj.updateValue(dv, false, true);
// }
//
// }
// }
}
}
} else if (fields != null && fields.length > 0) {
// The Fields entry refers to the fields we want to reset
// Iterate over all the forms and add those with the same names as in the fields array
// Use an array list as fields can potentially use the same name
final ArrayList formObjects = new ArrayList();
for (final Object allFormObject : allFormObjects) {
final FormObject formObject = (FormObject) allFormObject;
for (final String name : fields) {
if (name == null) {
continue;
}
// Check if the names are the same
if (formObject.getTextStreamValue(PdfDictionary.T).equals(name)) {
formObjects.add(formObject);
}
}
}
for (final FormObject formObject : formObjects) {
final String defaultValue = formObject.getTextStreamValue(PdfDictionary.DV);
formObject.updateValue(defaultValue, false, true);
// if(formObject.hasKeyArray(PdfDictionary.Kids)) {
// byte[][] kidList = formObject.getKeyArray(PdfDictionary.Kids);
// for (final byte[] aKidList : kidList) { //iterate through all parts
// String key = new String(aKidList);
// Object[] formComps = acrorend.getFormComponents(key, ReturnValues.FORMOBJECTS_FROM_REF, -1);
// for(int y = 0; y < formComps.length; y ++) {
// FormObject childObj = (FormObject) formComps[y];
// String dv = childObj.getTextStreamValue(PdfDictionary.DV);
// childObj.updateValue(dv, false, true);
// }
//
// }
// }
}
} else {
// Reset all forms
for (final Object allFormObject : allFormObjects) {
final FormObject formObject = (FormObject) allFormObject;
final String defaultValue = formObject.getTextStreamValue(PdfDictionary.DV);
formObject.updateValue(defaultValue, false, true);
// if(formObject.hasKeyArray(PdfDictionary.Kids)) {
// byte[][] kidList = formObject.getKeyArray(PdfDictionary.Kids);
// for (final byte[] aKidList : kidList) { //iterate through all parts
// String key = new String(aKidList);
// Object[] formComps = acrorend.getFormComponents(key, ReturnValues.FORMOBJECTS_FROM_REF, -1);
// for(int y = 0; y < formComps.length; y ++) {
// FormObject childObj = (FormObject) formComps[y];
// String dv = childObj.getTextStreamValue(PdfDictionary.DV);
// childObj.updateValue(dv, false, true);
// }
//
// }
// }
}
}
}
/**
* public as also called from Viewer to reset
*
* new page or -1 returned
*
* @param aData
* @param eventType
* @param command
* @return
*/
@Override
public int gotoDest(final PdfObject aData, final int eventType, int command) {
final boolean debugDest = false;
//new page or -1 returned
int page = -1;
if (showMethods) {
System.out.println("DefaultActionHandler.gotoDest()");
}
final PdfArrayIterator Dest = DestHandler.getDestFromObject(aData, currentPdfFile);
if (Dest != null) {
if (eventType == MOUSECLICKED) {
String filename = aData.getTextStreamValue(PdfDictionary.F);
if (filename == null) {
final PdfObject fDic = aData.getDictionary(PdfDictionary.F);
if (fDic != null) {
filename = fDic.getTextStreamValue(PdfDictionary.F);
}
}
//add path if none present
if (filename != null && filename.indexOf('/') == -1 && filename.indexOf('\\') == -1) {
filename = decode_pdf.getObjectStore().getCurrentFilepath() + filename;
}
//removed \\ checking from iff so slashIndex will work, and
//stop null pointer exceptions, \\ will also be quicker.
if (filename != null) {
//if we have any \\ then replace with / for Windows
int index = filename.indexOf('\\');
while (index != -1) {
//for some reason String.replaceAll didnt like "\\" so done custom
filename = filename.substring(0, index) +
'/' + filename.substring(index + ("\\".length()), filename.length());
index = filename.indexOf('\\');
}
//if we dont start with a /,./ or ../ or #:/ then add ./
final int slashIndex = filename.indexOf(":/");
if ((slashIndex == -1 || slashIndex > 1) && !filename.startsWith("/")) {
final File fileStart = new File(decode_pdf.getFileName());
filename = fileStart.getParent() + '/' + filename;
}
//resolve any ../ by removing
//(ie /home/test/Downloads/hyperlinks2/Data/../Start.pdf to
// /home/test/Downloads/hyperlinks2/Start.pdf)
index = filename.indexOf("/../");
if (index != -1) {
int start = index - 1;
while (start > 0) {
if ((filename.charAt(start) == '/') || start == 0) {
break;
}
start--;
}
if (start > 0) {
filename = filename.substring(0, start) + filename.substring(index + 3, filename.length());
}
}
}
// new version - read Page Object to jump to
String pageRef = "";
if (Dest.getTokenCount() > 0) {
//This will catch if the destination page is not set and continue without making changes
if (Dest.isNextValueNull()) {
return -1;
}
//get pageRef as number of ref
final int possiblePage = Dest.getNextValueAsInteger(false) + 1;
pageRef = Dest.getNextValueAsString(true);
//convert to target page if ref or ignore
if (pageRef.endsWith(" R")) {
page = decode_pdf.getPageFromObjectRef(pageRef);
} else if (possiblePage > 0) { //can also be a number (cant check range as not yet open)
page = possiblePage;
}
if (debugDest) {
System.out.println("pageRef=" + pageRef + " page=" + page + ' ' + aData.getObjectRefAsString());
}
//allow for named Dest
if (page == -1) {
final String newRef = currentPdfFile.convertNameToRef(pageRef);
//System.out.println(newRef+" "+decode_pdf.getIO().convertNameToRef(pageRef+"XX"));
if (newRef != null && newRef.endsWith(" R")) {
page = decode_pdf.getPageFromObjectRef(newRef);
}
}
//commented out by mark as named dest should now be handled and -1 shows no page
//if(page==-1){
//we probably have a named destination
// page = 1;
//}
}
//added by Mark so we handle these types of links as well in code below with no Dest
//<>
if (Dest.getTokenCount() == 0 && aData.getNameAsConstant(PdfDictionary.S) == PdfDictionary.GoToR) {
command = PdfDictionary.GoToR;
}
// boolean openInNewWindow = aData.getBoolean(PdfDictionary.NewWindow);
if (debugDest) {
System.out.println("Command=" + PdfDictionary.showAsConstant(command));
}
switch (command) {
case PdfDictionary.Dest:
//read all the values
if (Dest.getTokenCount() > 1) {
//get type of Dest
//System.out.println("Next value as String="+Dest.getNextValueAsString(false)); //debug code to show actual value (note false so does not roll on)
final int type = Dest.getNextValueAsConstant(true);
if (debugDest) {
System.out.println("Type=" + PdfDictionary.showAsConstant(type));
}
Integer scale = null;
Rectangle position = null;
// - I have added all the keys for you and
//changed code below. If you run this on baseline,
//with new debug flag testActions on in DefaultAcroRender
// it will exit when it hits one
//not coded
//type of Dest (see page 552 in 1.6Spec (Table 8.2) for full list)
switch (type) {
case PdfDictionary.XYZ: //get X,y values and convert to rectangle which we store for later
//get x and y, (null will return 0)
final float x = Dest.getNextValueAsFloat();
final float y = Dest.getNextValueAsFloat();
//third value is zoom which is not implemented yet
//create Rectangle to scroll to
position = new Rectangle((int) x, (int) y, 10, 10);
break;
case PdfDictionary.Fit: //type sent in so that we scale to Fit.
scale = -3; //0 for width in scaling box and -3 to show its an index
break;
case PdfDictionary.FitB:
/*[ page /FitB ] - (PDF 1.1) Display the page designated by page, with its contents
* magnified just enough to fit its bounding box entirely within the window both
* horizontally and vertically. If the required horizontal and vertical magnification
* factors are different, use the smaller of the two, centering the bounding box
* within the window in the other dimension.
*/
//scale to same as Fit so use Fit.
scale = -3; //0 for width in scaling box and -3 to show its an index
break;
case PdfDictionary.FitH:
/* [ page /FitH top ] - Display the page designated by page, with the vertical coordinate
* top positioned at the top edge of the window and the contents of the page magnified
* just enough to fit the entire width of the page within the window. A null value for
* top specifies that the current value of that parameter is to be retained unchanged.
*/
//scale to width
scale = -1; //2 for width in scaling box and -3 to show its an index
if (Dest.hasMoreTokens()) { //value optional
//and then scroll to location
final float top = Dest.getNextValueAsFloat();
//create Rectangle to scroll to
position = new Rectangle(10, (int) top, 10, 10);
}
break;
case PdfDictionary.FitR:
/* [ page /FitR left bottom right top ] - Display the page designated by page, with its
* contents magnified just enough to fit the rectangle specified by the coordinates left,
* bottom, right, and topentirely within the window both horizontally and vertically.
* If the required horizontal and vertical magnification factors are different, use
* the smaller of the two, centering the rectangle within the window in the other
* dimension. A null value for any of the parameters may result in unpredictable behavior.
*/
//create Rectangle to scroll to
// position=new Rectangle((int)fitR_left,(int)fitR_top,(int)(fitR_right-fitR_left),(int)(fitR_top-fitR_bottom));
break;
/* [ page /FitV left ] - Display the page designated by page, with the horizontal
* coordinate left positioned at the left edge of the window and the contents of
* the page magnified just enough to fit the entire height of the page within the window.
* A null value for left specifies that the current value of that parameter is to be
* retained unchanged.
*/
/* [ page /FitB ] - (PDF 1.1) Display the page designated by page, with its contents
* magnified just enough to fit its bounding box entirely within the window both
* horizontally and vertically. If the required horizontal and vertical magnification
* factors are different, use the smaller of the two, centering the bounding box within
* the window in the other dimension.
*/
/* [ page /FitBH top ] - (PDF 1.1) Display the page designated by page, with the vertical
* coordinate top positioned at the top edge of the window and the contents of the page
* magnified just enough to fit the entire width of its bounding box within the window.
* A null value for top specifies that the current value of that parameter is to be retained
* unchanged.
*/
/* [ page /FitBV left ] - (PDF 1.1) Display the page designated by page, with the horizontal
* coordinate left positioned at the left edge of the window and the contents of the page
* magnified just enough to fit the entire height of its bounding box within the window.
* A null value for left specifies
*/
}
changeTo(filename, page, position, scale, true);
}
break;
case PdfDictionary.GoTo:
// S /Goto or /GoToR action is a goto remote file action,
// F specifies the file (GoToR only)
// D specifies the location or page
if (page != -1) {
changeTo(null, page, null, null, true);
}
break;
case PdfDictionary.GoToR:
//A /GoToR action is a goto remote file action,
//F specifies the file
//D specifies the location or page
//NewWindow a flag specifying whether to open it in a new window.
final int index = pageRef.indexOf("P.");
if (index != -1) {
pageRef = pageRef.substring(index + 2, pageRef.length());
page = Integer.parseInt(pageRef);
} else if (pageRef.equals("F")) {
//use file only
page = 1;
} else {
//if no pageRef defined default to one, confirmed by working example
page = 1;
}
//NOTE: filename full authenticated above dont redo.
if (new File(filename).exists()) {
//Open this file, on page 'page'
if (page != -1) {
changeTo(filename, page, null, null, true);
}
LogWriter.writeFormLog("{DefaultActionHamdler.A} Form has GoToR command, needs methods for opening new file on page specified", FormStream.debugUnimplemented);
} else {
showMessageDialog("The file specified " + filename + " Does Not Exist!");
}
break;
}
}
}
return page;
}
/**
* this calls the PdfDecoder to open a new page and change to the correct page and location on page,
* is any value is null, it means leave as is.
*
* @param type - the type of action
*/
@Override
public void changeTo(final String file, final int page, final Object location, final Integer type, final boolean storeView) {
if (showMethods) {
System.out.println("DefaultActionHandler.changeTo()" + file);
}
}
@Override
public PdfDecoderInt getPDFDecoder() {
return decode_pdf;
}
/**
* E action when cursor enters active area
*/
@Override
public void E(final Object e, final FormObject formObj) {
if (showMethods) {
System.out.println("DefaultActionHandler.E()");
}
javascript.execute(formObj, PdfDictionary.E, ActionHandler.FOCUS_EVENT, ' ');
}
/**
* X action when cursor exits active area
*/
@Override
public void X(final Object e, final FormObject formObj) {
if (showMethods) {
System.out.println("DefaultActionHandler.X()");
}
javascript.execute(formObj, PdfDictionary.X, ActionHandler.FOCUS_EVENT, ' ');
}
/**
* D action when cursor button pressed inside active area
*/
@Override
public void D(final Object e, final FormObject formObj) {
if (showMethods) {
System.out.println("DefaultActionHandler.D()");
}
javascript.execute(formObj, PdfDictionary.D, ActionHandler.FOCUS_EVENT, ' ');
}
/**
* U action when cursor button released inside active area
*/
@Override
public void U(final Object e, final FormObject formObj) {
if (showMethods) {
System.out.println("DefaultActionHandler.U()");
}
javascript.execute(formObj, PdfDictionary.U, ActionHandler.FOCUS_EVENT, ' ');
}
/**
* Fo action on input focus
*/
@Override
public void Fo(final Object e, final FormObject formObj) { //TODO called with focus gained
if (showMethods) {
System.out.println("DefaultActionHandler.Fo()");
}
javascript.execute(formObj, PdfDictionary.Fo, ActionHandler.FOCUS_EVENT, ' ');
}
/**
* Bl action when input focus lost, blur
*/
@Override
public void Bl(final Object e, final FormObject formObj) { // TODO called by focus lost
if (showMethods) {
System.out.println("DefaultActionHandler.Bl()");
}
javascript.execute(formObj, PdfDictionary.Bl, ActionHandler.FOCUS_EVENT, ' ');
}
/**
* O called when a page is opened
*/
@Override
public void O(final PdfObject pdfObject, final int type) {
if (currentPdfFile == null) {
return;
}
if (showMethods) {
System.out.println("DefaultActionHandler.O()");
}
final FormObject pageDictionary = (FormObject) pdfObject.getDictionary(type);
currentPdfFile.checkResolved(pageDictionary);
if (pageDictionary != null) {
final FormObject Odictionary = (FormObject) pageDictionary.getDictionary(PdfDictionary.O);
currentPdfFile.checkResolved(Odictionary);
if (Odictionary != null) {
String jsCode = Odictionary.getTextStreamValue(PdfDictionary.JS);
if (jsCode == null) {
final PdfObject JS = Odictionary.getDictionary(PdfDictionary.JS);
if (JS != null)//in stream
{
jsCode = new String(JS.getDecodedStream());
}
}
javascript.executeAction(jsCode);
}
}
}
/**
* PO action when page containing is opened,
* actions O of pages AA dic, and OpenAction in document catalog should be done first
*/
@Override
public void PO(final PdfObject pdfObject, final int type) {
if (currentPdfFile == null) {
return;
}
if (showMethods) {
System.out.println("DefaultActionHandler.PO()");
}
final FormObject pageDictionary = (FormObject) pdfObject.getDictionary(type);
currentPdfFile.checkResolved(pageDictionary);
if (pageDictionary != null) {
final FormObject POdictionary = (FormObject) pageDictionary.getDictionary(PdfDictionary.PO);
currentPdfFile.checkResolved(POdictionary);
if (POdictionary != null) {
final String jsCode = POdictionary.getTextStreamValue(PdfDictionary.JS);
javascript.executeAction(jsCode);
}
}
}
/**
* PC action when page is closed, action C from pages AA dic follows this
*/
@Override
public void PC(final PdfObject pdfObject, final int type) {
if (showMethods) {
System.out.println("DefaultActionHandler.PC()");
}
final FormObject pageDictionary = (FormObject) pdfObject.getDictionary(type);
currentPdfFile.checkResolved(pageDictionary);
if (pageDictionary != null) {
final FormObject PCdictionary = (FormObject) pageDictionary.getDictionary(PdfDictionary.PC);
currentPdfFile.checkResolved(PCdictionary);
if (PCdictionary != null) {
final String jsCode = PCdictionary.getTextStreamValue(PdfDictionary.JS);
javascript.executeAction(jsCode);
}
}
}
/**
* PV action on viewing containing page
*/
@Override
public void PV(final PdfObject pdfObject, final int type) {
if (showMethods) {
System.out.println("DefaultActionHandler.PV()");
}
final FormObject pageDictionary = (FormObject) pdfObject.getDictionary(type);
currentPdfFile.checkResolved(pageDictionary);
if (pageDictionary != null) {
final FormObject PVdictionary = (FormObject) pageDictionary.getDictionary(PdfDictionary.PV);
currentPdfFile.checkResolved(PVdictionary);
if (PVdictionary != null) {
final String jsCode = PVdictionary.getTextStreamValue(PdfDictionary.JS);
javascript.executeAction(jsCode);
}
}
}
/**
* PI action when page no longer visible in viewer
*/
@Override
public void PI(final PdfObject pdfObject, final int type) {
if (showMethods) {
System.out.println("DefaultActionHandler.PI()");
}
final FormObject pageDictionary = (FormObject) pdfObject.getDictionary(type);
currentPdfFile.checkResolved(pageDictionary);
if (pageDictionary != null) {
final FormObject PIdictionary = (FormObject) pageDictionary.getDictionary(PdfDictionary.PI);
currentPdfFile.checkResolved(PIdictionary);
if (PIdictionary != null) {
final String jsCode = PIdictionary.getTextStreamValue(PdfDictionary.JS);
javascript.executeAction(jsCode);
// Scan through the fields and change any that have changed
//acrorend.updateChangedForms();
}
}
}
/**
* when user types a keystroke
* K action on - [javascript]
* keystroke in textfield or combobox
* modifys the list box selection
* (can access the keystroke for validity and reject or modify)
*/
@Override
public int K(final Object ex, final FormObject formObj, final int actionID) {
if (showMethods) {
System.out.println("DefaultActionHandler.K()");
}
final int result = javascript.execute(formObj, PdfDictionary.K, actionID, getKeyPressed(ex));
final int fontSize = formObj.getTextSize();
if (acrorend.getCompData() != null && (fontSize == 0 || fontSize == -1)) {
acrorend.getCompData().setAutoFontSize(formObj);
}
return result;
}
/**
* F the display formatting of the field (e.g 2 decimal places) [javascript]
*/
@Override
public void F(final FormObject formObj) {
if (showMethods) {
System.out.println("DefaultActionHandler.F()");
}
javascript.execute(formObj, PdfDictionary.F, ActionHandler.FOCUS_EVENT, ' ');
}
/**
* V action when fields value is changed [javascript], validate
*/
@Override
public void V(final Object ex, final FormObject formObj, final int actionID) {
if (showMethods) {
System.out.println("DefaultActionHandler.V()");
}
javascript.execute(formObj, PdfDictionary.V, actionID, getKeyPressed(ex));
}
final Map Ccalled = new HashMap();
/**
* C action when another field changes (recalculate this field) [javascript]
*
* NOT actually called as called from other other objects but here for completeness
*/
@Override
public void C(final FormObject formObj) {
if (showMethods) {
System.out.println("DefaultActionHandler.C() called from=" + formObj.getObjectRefAsString());
}
if (Ccalled.get(formObj.getObjectRefAsString()) != null) {
return;
}
Ccalled.put(formObj.getObjectRefAsString(), "1");
javascript.execute(formObj, PdfDictionary.C2, ActionHandler.FOCUS_EVENT, ' ');
Ccalled.remove(formObj.getObjectRefAsString());
}
/**
* goes through the map and adds the required data to the hideMap and returns it
*/
private static void getHideMap(final PdfObject aData, final FieldsHideObject fieldToHide) {
if (showMethods) {
System.out.println("DefaultActionHandler.getHideMap()");
}
String[] fieldstoHide = fieldToHide.getFieldArray();
boolean[] whethertoHide = fieldToHide.getHideArray();
if (aData.getTextStreamValue(PdfDictionary.T) != null) {
final String fieldList = aData.getTextStreamValue(PdfDictionary.T);
if (fieldList != null) {
final String[] fields;
if (fieldstoHide.length > 0) {
fields = new String[fieldstoHide.length + 1];
System.arraycopy(fieldstoHide, 0, fields, 0, fieldstoHide.length);
fields[fields.length - 1] = fieldList;
} else {
fields = new String[]{fieldList};
}
fieldstoHide = fields;
}
}
final boolean hideFlag = aData.getBoolean(PdfDictionary.H);
final boolean[] hideFlags;
if (whethertoHide.length > 0) {
hideFlags = new boolean[whethertoHide.length + 1];
System.arraycopy(whethertoHide, 0, hideFlags, 0, whethertoHide.length);
hideFlags[hideFlags.length - 1] = hideFlag;
} else {
hideFlags = new boolean[]{hideFlag};
}
whethertoHide = hideFlags;
//put values back into fields to hide object
fieldToHide.setFieldArray(fieldstoHide);
fieldToHide.setHideArray(whethertoHide);
if (aData.getDictionary(PdfDictionary.Next) != null) {
final PdfObject nextDic = aData.getDictionary(PdfDictionary.Next);
getHideMap(nextDic, fieldToHide);
}
}
public static void showMessageDialog(final String s) {
JOptionPane.showMessageDialog(null, s);
}
/**
* pick up key press or return ' '
*/
public static char getKeyPressed(final Object raw) {
try {
final ComponentEvent ex = (ComponentEvent) raw;
if (ex instanceof KeyEvent) {
return ((KeyEvent) ex).getKeyChar();
} else {
return ' ';
}
} catch (final Exception ee) {
System.out.println("Exception " + ee);
}
return ' ';
}
/**
* shows and hides the appropriate fields as defined within the map defined
*
* @param fieldToHide - the field names to which we want to hide
* both arrays must be the same length.
*/
public void setFieldVisibility(final FieldsHideObject fieldToHide) {
final String[] fieldsToHide = fieldToHide.getFieldArray();
final boolean[] whetherToHide = fieldToHide.getHideArray();
if (fieldsToHide.length != whetherToHide.length) {
//this will exit internally only and the production version will carry on regardless.
LogWriter.writeFormLog("{custommouselistener} number of fields and nuber of hides or not the same", FormStream.debugUnimplemented);
return;
}
for (int i = 0; i < fieldsToHide.length; i++) {
hideComp(fieldsToHide[i], !whetherToHide[i]);
}
}
private void hideComp(final String compName, final boolean visible) {
final Object[] checkObj = acrorend.getFormComponents(compName, ReturnValues.FORMOBJECTS_FROM_NAME, -1);
final Object[] allObj = acrorend.getFormComponents(compName, ReturnValues.FORMOBJECTS_FROM_NAME, -1);
if (checkObj != null) {
for (final Object obj : allObj) {
final FormObject formObject = (FormObject) obj;
final Rectangle rect = formObject.getBoundingRectangle();
if (rect == null) {
continue;
}
//we need the index for the object so we can check the bounding boxes
final float rx = rect.x;
final float ry = rect.y;
final float rwidth = rect.width;
final float rheight = rect.height;
final Rectangle rootRect = new Rectangle((int) rx, (int) ry, (int) rwidth, (int) rheight);
//find components hidden within this components bounds and hide
for (final Object possiblyHiddenObj : allObj) {
final FormObject formObject2 = (FormObject) possiblyHiddenObj;
if (formObject2 != null && formObject2.getBoundingRectangle() != null && rootRect.contains(formObject2.getBoundingRectangle())) {
formObject2.setVisible(!visible);
}
}
//checkGUIObjectResolved(formObject);
formObject.setVisible(visible);
}
}
}
/**
* @param listOfFields - defines a list of fields to either include or exclude from the submit option,
* Dependent on the flag, if is null all fields are submitted.
* @param excludeList - if true then the listOfFields defines an exclude list,
* if false the list is an include list, if listOfFields is null then this field is ignored.
* @param submitURL - the URL to submit to.
*/
private void submitURL(final String[] listOfFields, final boolean excludeList, final String submitURL) {
if (submitURL != null) {
Component[] compsToSubmit = new Component[0];
String[] includeNameList = new String[0];
if (listOfFields != null) {
if (excludeList) {
//listOfFields defines an exclude list
//Object[] forms = acrorend.getFormComponents(null, ReturnValues.FORM_NAMES, -1);
} else {
//fields is an include list
includeNameList = listOfFields;
}
Component[] compsToAdd, tmp;
for (int i = 0; i < includeNameList.length; i++) {
compsToAdd = (Component[]) acrorend.getFormComponents(includeNameList[i], ReturnValues.GUI_FORMS_FROM_NAME, -1);
if (compsToAdd != null) {
tmp = new Component[compsToSubmit.length + compsToAdd.length];
if (compsToAdd.length > 1) {
LogWriter.writeFormLog("(internal only) SubmitForm multipul components with same name", FormStream.debugUnimplemented);
if (FormStream.debugUnimplemented) {
org.jpedal.objects.acroforms.utils.ConvertToString.printStackTrace(1);
}
}
for (int k = 0; i < tmp.length; k++) {
if (k < compsToSubmit.length) {
tmp[k] = compsToSubmit[k];
} else if (k - compsToSubmit.length < compsToAdd.length) {
tmp[k] = compsToAdd[k - compsToSubmit.length];
}
}
compsToSubmit = tmp;
}
}
} else {
compsToSubmit = (Component[]) acrorend.getFormComponents(null, ReturnValues.GUI_FORMS_FROM_NAME, -1);
}
final StringBuilder text = new StringBuilder();
if (compsToSubmit != null && compsToSubmit.length > 0) {
for (final Component aCompsToSubmit : compsToSubmit) {
if (aCompsToSubmit instanceof JTextComponent) {
text.append(((JTextComponent) aCompsToSubmit).getText());
} else if (aCompsToSubmit instanceof AbstractButton) {
text.append(((AbstractButton) aCompsToSubmit).getText());
} else if (aCompsToSubmit != null) {
LogWriter.writeFormLog("(internal only) SubmitForm field form type not accounted for", FormStream.debugUnimplemented);
}
}
}
}
}
protected void popup(final Object raw, final FormObject formObj, final PdfObjectReader currentPdfFile) {
if (((MouseEvent) raw).getClickCount() == 2) {
//find the popup dictionary so we can get the ref (we do this to get the ref so we can lookup)
final FormObject popupObj = (FormObject) formObj.getDictionary(PdfDictionary.Popup);
currentPdfFile.checkResolved(popupObj);
//use the ref to lookup the actual instance where the gui comp will be stored in
final FormObject decodedObj = this.acrorend.getFormObject(popupObj.getObjectRefAsString());
//if it exists toggle on/off
final Object comp = decodedObj.getGUIComponent();
if (comp != null) {
//and we need a seperate popup for each field.
final JComponent popup = (JComponent) comp;
if (popup.isVisible()) {
popup.setVisible(false);
} else {
popup.setVisible(true);
}
}
//move focus so that the button does not flash
((Component) ((EventObject) raw).getSource()).setFocusable(false);
}
}
@Override
public PdfLayerList getLayerHandler() {
if (decode_pdf == null) {
return null;
}
final Object layer = decode_pdf.getJPedalObject(PdfDictionary.Layer);
if (layer == null) {
return null;
} else {
return (PdfLayerList) layer;
}
}
}