Package org.jpedal.objects.acroforms.actions

Source Code of org.jpedal.objects.acroforms.actions.DefaultActionHandler

/**
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info:  http://www.jpedal.org
* (C) Copyright 1997-2008, IDRsolutions and Contributors.
*
*   This file is part of JPedal
*
    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


*
* ---------------
* DefaultActionHandler.java
* ---------------
*/
package org.jpedal.objects.acroforms.actions;

import org.jpedal.Display;
import org.jpedal.PdfDecoder;
//<start-adobe><start-thin>
import org.jpedal.examples.simpleviewer.gui.SwingGUI;
import org.jpedal.examples.simpleviewer.gui.swing.SwingMouseListener;
import org.jpedal.examples.simpleviewer.Commands;
import org.jpedal.examples.simpleviewer.SimpleViewer;
import org.jpedal.examples.simpleviewer.Values;
import org.jpedal.external.Options;
//<end-thin><end-adobe>
import org.jpedal.io.ArrayDecoder;
import org.jpedal.io.ObjectDecoder;
import org.jpedal.io.ObjectStore;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.Javascript;
import org.jpedal.objects.layers.PdfLayerList;
import org.jpedal.objects.acroforms.actions.privateclasses.FieldsHideObject;
import org.jpedal.objects.acroforms.formData.ComponentData;
import org.jpedal.objects.raw.FormStream;
import org.jpedal.objects.raw.FormObject;
import org.jpedal.objects.raw.PdfArrayIterator;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.objects.acroforms.rendering.AcroRenderer;
import org.jpedal.objects.acroforms.rendering.DefaultAcroRenderer;
import org.jpedal.objects.acroforms.utils.ConvertToString;
import org.jpedal.objects.raw.*;
import org.jpedal.utils.BrowserLauncher;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.Messages;
import org.jpedal.utils.StringUtils;

import javax.swing.*;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;



public class DefaultActionHandler implements ActionHandler {
 
  final static private boolean showMethods = false;

  //shows the form you have hovered over with the mouse
  private static final boolean IdentifyForms = false;/**/

    private PdfObjectReader currentPdfFile;

    private Javascript javascript;

  private AcroRenderer acrorend;

    private ActionFactory actionFactory;

    //handle so we can access
  private PdfDecoder decode_pdf;

  //private int pageHeight,insetH;

  //flags to control reading of JS
  private boolean JSInitialised_A, JSInitialised_BI,JSInitialised_C, JSInitialised_D,
  JSInitialised_E,JSInitialised_F, JSInitialised_Fo, JSInitialised_K, JSInitialised_U,
  JSInitialised_V, JSInitialised_X;

  //<start-adobe><start-thin>
  private SwingMouseListener swingMouseHandler;
  //<end-thin><end-adobe>

  public void init(PdfDecoder decode_pdf, Javascript javascript, 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;

    }
 
//  public void init(PdfObjectReader pdfFile, Javascript javascript, AcroRenderer acrorend) {
//    if(showMethods)
//      System.out.println("DefaultActionHandler.init()");
//
//    currentPdfFile = pdfFile;
//    this.javascript = javascript;
//    this.acrorend = acrorend;
//   
//    }

  public void setPageAccess(int pageHeight, int insetH) {
    if(showMethods)
      System.out.println("DefaultActionHandler.setPageAccess()");
   
    //this.pageHeight=pageHeight;
    //this.insetH=insetH;
  }

    public void setActionFactory(ActionFactory actionFactory) {
      if(showMethods)
        System.out.println("DefaultActionHandler.setActionFactory()");

        actionFactory.setPDF(decode_pdf,acrorend);
        this.actionFactory=actionFactory;

    }
   
    public ActionFactory getActionFactory(){
      return actionFactory;
    }

    /**
   * creates a returns an action listener that will change the down icon for each click
   */
  public Object setupChangingDownIcon(Object downOff, Object downOn, int rotation) {
    if(showMethods)
      System.out.println("DefaultActionHandler.setupChangingDownIcon()");
   
    return actionFactory.getChangingDownIconListener(downOff, downOn, rotation);
  }

  /**
   * sets up the captions to change as needed
   */
  public Object setupChangingCaption(String normalCaption, String rolloverCaption, String downCaption) {
    if(showMethods)
      System.out.println("DefaultActionHandler.setupChangingCaption()");
   
    return new SwingFormButtonListener(normalCaption, rolloverCaption, downCaption);
  }
 
  public Object setHoverCursor(){
    if(showMethods)
      System.out.println("DefaultActionHandler.setHoverCursor()");
   
    return actionFactory.getHoverCursor();
   
  }

        /**
         * A action when pressed in active area ?some others should now be ignored?
         */
        public void A(Object raw, FormObject formObj, int eventType) {
           
        if(showMethods)
            System.out.println("DefaultActionHandler.A() ");
           
           
            // 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){
                    if(eventType == MOUSEENTERED){
                        aData = aData.getDictionary(PdfDictionary.E);
                    }else if(eventType == MOUSEEXITED){
                        aData = aData.getDictionary(PdfDictionary.X);
                    }else if(eventType == MOUSEPRESSED){
                        aData = aData.getDictionary(PdfDictionary.D);
                    }else if(eventType == MOUSERELEASED){
                        aData = aData.getDictionary(PdfDictionary.U);
                    }
                }
            }
           
            //change cursor for each event
            actionFactory.setCursor(eventType);
           
            gotoDest(formObj,eventType,PdfDictionary.Dest);
           
            int subtype=formObj.getParameterConstant(PdfDictionary.Subtype);
           
            int popupFlag = formObj.getActionFlag();
           
            if (subtype == PdfDictionary.Sig) {
               
                additionalAction_Signature(formObj, eventType);
               
            } else if (eventType==MOUSECLICKED && (popupFlag == FormObject.POPUP || subtype==PdfDictionary.Text)){
                actionFactory.popup(raw,formObj,currentPdfFile);
            } else {
                // can get empty values
                if (aData == null)
                    return;
               
                int command = aData.getNameAsConstant(PdfDictionary.S);
               
                // S is Name of action
                if (command != PdfDictionary.Unknown) {
                   
                    if (command == PdfDictionary.Named) {
                       
                        additionalAction_Named(eventType, aData);
                       
                    }else if(command==PdfDictionary.Goto || command==PdfDictionary.GoToR){
                        if (aData != null) {
                            gotoDest(aData, eventType,command);
                        }
                    } else if (command == PdfDictionary.ResetForm) {
                       
                        additionalAction_ResetForm();
                       
                    } else if (command == PdfDictionary.SubmitForm) {
                       
                        additionalAction_SubmitForm(aData);
                       
                    } else if (command == PdfDictionary.JavaScript) {
                       
                        //javascript called above.
                       
                    } else if (command == PdfDictionary.Hide) {
                       
                        additionalAction_Hide(eventType, aData);
                       
                    } else if (command == PdfDictionary.URI) {
                       
                        additionalAction_URI(eventType, aData.getTextStreamValue(PdfDictionary.URI));
                       
                    } else if (command == PdfDictionary.Launch) {
                       
                        //<start-thin><start-adobe>
                        try {
                            //get the F dictionary
                            PdfObject dict=aData.getDictionary(PdfDictionary.F);
                           
                            //System.out.println("dict="+dict+" "+dict.getObjectRefAsString());
                           
                            //then get the submit URL to use
                            if(dict!=null){
                                String target = dict.getTextStreamValue(PdfDictionary.F);
                               
                                InputStream sourceFile = getClass().getResourceAsStream("/org/jpedal/res/"+target);
                               
                                if(sourceFile==null){
                                    JOptionPane.showMessageDialog(decode_pdf,"Unable to locate "+target);
                                }else{
                                    //System.out.printl("name="+getClass().getResource("/org/jpedal/res/"+target).get);
                                   
                                    //get name without path
                                    int ptr=target.lastIndexOf("/");
                                    if(ptr!=-1)
                                        target=target.substring(ptr+1);
                                   
                                    File output=new File(ObjectStore.temp_dir+target);
                                    output.deleteOnExit();
                                   
                                    ObjectStore.copy(new BufferedInputStream(sourceFile),
                                            new BufferedOutputStream(new FileOutputStream(output)));
                                   
                                    if(target.endsWith(".pdf")){
                                       
                                        try{
                                            SimpleViewer viewer=new SimpleViewer(Values.RUNNING_NORMAL);
                                            SimpleViewer.exitOnClose=false;
                                           
                                            //<start-wrap>
                                            /**
                                        //<end-wrap>
                                        viewer.setupViewer(ObjectStore.temp_dir+target);
                                        /**/
                                            //<start-wrap>
                                            viewer.setupViewer();
                                            viewer.openDefaultFile(ObjectStore.temp_dir+target);
                                            //<end-wrap>

                                        }catch(Exception e){
                                            e.printStackTrace();
                                        }

                                    }else if(PdfDecoder.isRunningOnMac){
                                        target="open "+ObjectStore.temp_dir+target;

                                        Runtime.getRuntime().exec(target);
                                }
                            }
                               
                            }
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        } catch (Error err) {
                            err.printStackTrace();
                        }
                       
                        //<end-adobe><end-thin>
                       
                        LogWriter.writeFormLog("{stream} launch activate action NOT IMPLEMENTED", FormStream.debugUnimplemented);
                       
                    } else if (command == PdfDictionary.SetOCGState) {
                       
                        additionalAction_OCState(eventType, aData);
                       
                    } else if (command == PdfDictionary.Sound) {
                       
                       
                    } else {
                        LogWriter.writeFormLog("{stream} UNKNOWN Command "+aData.getName(PdfDictionary.S)+" Action", FormStream.debugUnimplemented);
                    }
                } else if(command!=-1){
                    LogWriter.writeFormLog("{stream} Activate Action UNKNOWN command "+aData.getName(PdfDictionary.S)+ ' ' +formObj.getObjectRefAsString(), FormStream.debugUnimplemented);
                }
            }
        }
       
  private void additionalAction_OCState(int eventType, PdfObject aData) {
    if (eventType == MOUSECLICKED) {

      PdfArrayIterator state = aData.getMixedArray(PdfDictionary.State);

      if (state != null && state.getTokenCount() > 0) {

        final PdfLayerList layers = (PdfLayerList)decode_pdf.getJPedalObject(PdfDictionary.Layer);

        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
          Runnable updateAComponent = new Runnable() {
            public void run() {
              // force refresh
              decode_pdf.invalidate();
              decode_pdf.validate();

              // update settings on display and in PdfDecoder
              boolean newState;
              if (action == PdfDictionary.Toggle)
                newState = !layers.isVisible(layerName);
              else if (action == PdfDictionary.OFF)
                newState = false;
                            else //must be ON
                newState = true;

              layers.setVisiblity(layerName, newState);

              // decode again with new settings
              try {
                decode_pdf.decodePage(-1);
              } catch (Exception e) {
                                e.printStackTrace()//To change body of catch statement use File | Settings | File Templates.
              }
            }
          };

          SwingUtilities.invokeLater(updateAComponent);
        }
      }
    }
  }

  private void additionalAction_Named(int eventType, PdfObject aData) {
    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){
      //<start-adobe><start-thin>
            SwingGUI swingGUI=((SwingGUI)decode_pdf.getExternalHandler(Options.SwingContainer));

            if(swingGUI!=null)
              swingGUI.currentCommands.executeCommand(Commands.BACK,null);
            //<end-thin><end-adobe>
    }else if(name == PdfDictionary.LastPage){
      changeTo(null, decode_pdf.getPageCount(), null, null,true);
    }else if(name == PdfDictionary.ZoomTo){
      //create scaling values list, taken from SimpleViewer.init(resourceBundle)
      JComboBox scaling = new JComboBox(new String[]{Messages.getMessage("PdfViewerScaleWindow.text"),Messages.getMessage("PdfViewerScaleHeight.text"),
          Messages.getMessage("PdfViewerScaleWidth.text"),
          "25","50","75","100","125","150","200","250","500","750","1000"});
      int option = JOptionPane.showConfirmDialog(null, scaling, Messages.getMessage("PdfViewerToolbarScaling.text")+ ':', JOptionPane.DEFAULT_OPTION);
     
             //<start-adobe><start-thin>
      if(option!=-1){
        int selection = scaling.getSelectedIndex();
        if(selection!=-1){
          SwingGUI swing = ((SwingGUI)decode_pdf.getExternalHandler(Options.SwingContainer));
                    if(swing!=null){
              swing.setSelectedComboIndex(Commands.SCALING, selection);
              swing.zoom(false);
                    }
        }
      }
      //<end-thin><end-adobe>
    }else if(name == PdfDictionary.FullScreen){
            //<start-adobe><start-thin>
            SwingGUI swingGUI=((SwingGUI)decode_pdf.getExternalHandler(Options.SwingContainer));

            if(swingGUI!=null)
      swingGUI.currentCommands.executeCommand(Commands.FULLSCREEN,null);
            //<end-thin><end-adobe>
    }else if(name == PdfDictionary.AcroForm_FormsJSGuide) {//AcroForm:FormsJSGuide
                    //<start-adobe><start-thin>
            String acrobatJSGuideURL = "http://www.adobe.com/devnet/acrobat/pdfs/Acro6JSGuide.pdf";
            int option = JOptionPane.showConfirmDialog(null, Messages.getMessage("AcroForm_FormsJSGuide.urlQuestion")
                            + '\n' + acrobatJSGuideURL + " ?\n\n"
                            + Messages.getMessage("AcroForm_FormsJSGuide.urlFail"), Messages.getMessage("AcroForm_FormsJSGuide.Title"), JOptionPane.YES_NO_OPTION);

                    if (option == 0) {
                        SimpleViewer viewer = new SimpleViewer(Values.RUNNING_NORMAL);
                        SimpleViewer.exitOnClose = false;

                        //<start-wrap>
                        /**
                        //<end-wrap>
                        viewer.setupViewer(AcrobatJSGuideURL);
                        /**/
                        //<start-wrap>
                        viewer.setupViewer();
                        viewer.openDefaultFile(acrobatJSGuideURL);
                        //<end-wrap>

                    }
                    //<end-thin><end-adobe>
                } else {

    }
  }
 
  private void additionalAction_SaveAs() {
    //- we should call it directly - I have put code below from Commands
   
    //<start-adobe><start-thin>
    SwingGUI swingGUI=((SwingGUI)decode_pdf.getExternalHandler(Options.SwingContainer));

    if(swingGUI!=null)
             swingGUI.currentCommands.executeCommand(Commands.SAVEFORM, null);
    //<end-thin><end-adobe>
  }

  private void additionalAction_URI(int eventType, String url) {
   
    if (showMethods)
      System.out.println("DefaultActionHandler.additionalAction_URI()");
   
    //as we only call this now when we need to action the url just call it.
    try {
      BrowserLauncher.openURL(url);
    } catch (IOException e1) {
      actionFactory.showMessageDialog(Messages.getMessage("PdfViewer.ErrorWebsite"));
    }
  }

  private void additionalAction_Hide(int eventType, PdfObject aData) {
    if (showMethods)
      System.out.println("DefaultActionHandler.additionalAction_Hide()");

      FieldsHideObject fieldsToHide = new FieldsHideObject();
         
      getHideMap(aData, fieldsToHide);

      actionFactory.setFieldVisibility(fieldsToHide);
  }

  private void additionalAction_SubmitForm(PdfObject aData) {
    if(showMethods)
      System.out.println("DefaultActionHandler.additionalAction_SubmitForm()");
   
    boolean newExcludeList=false;
    String newSubmitURL=null;
    String[] newListOfFields=null;
   
    //get the F dictionary
        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
        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;
        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")) {

                       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
      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
    actionFactory.submitURL(newListOfFields, newExcludeList, newSubmitURL);
  }

  private void additionalAction_ResetForm() {
    if (showMethods)
        System.out.println("DefaultActionHandler.additionalAction_ResetForm()");

    actionFactory.reset(null);
  }

    /**
     * public as also called from Viewer to reset
     *
     * new page or -1 returned
     * @param aData
     * @param eventType
     * @param command
     */
        public int gotoDest(PdfObject aData, int eventType, int command) {
           
        final boolean debugDest=false;
           
            //aData can either be in top level of Form (as in Annots)
            //or second level (as in A/ /D - this allows for both
            //whoch this routine handles
            PdfObject a2=aData.getDictionary(PdfDictionary.A);
            if(a2!=null)
                aData=a2;
           
            //new page or -1 returned
            int page=-1;
           
        if (showMethods)
                System.out.println("DefaultActionHandler.gotoDest()");
           
            PdfArrayIterator Dest = aData.getMixedArray(PdfDictionary.Dest);
            if (Dest!=null) {
               
                if (eventType == MOUSECLICKED) {
                   
                    //allow for it being an indirect named object and convert if so
                    if(Dest.getTokenCount()==1){
                        //          System.out.println("val="+ Dest.getNextValueAsString(false));
                       
                        String ref=decode_pdf.getIO().convertNameToRef( Dest.getNextValueAsString(false));
                        if(ref!=null){
                           
                            //can be indirect object stored between []
                            if(ref.charAt(0)=='['){
                                if(debugDest)
                                    System.out.println("data for named obj "+ref);
                               
                                byte[] raw=StringUtils.toBytes(ref);
                                //replace char so subroutine works -ignored but used as flag in routine
                                raw[0]= 0;
                               
                                ArrayDecoder objDecoder=new ArrayDecoder(decode_pdf.getIO().getObjectReader(), 0, raw.length, PdfDictionary.VALUE_IS_MIXED_ARRAY,null, PdfDictionary.Names);
                                objDecoder.readArray(false, raw, aData, PdfDictionary.Dest);
                               
                                Dest=aData.getMixedArray(PdfDictionary.Dest);
                               
                            }else{
                                if(debugDest)
                                    System.out.println("convert named obj "+ref);
                               
                                aData=new OutlineObject(ref);
                                decode_pdf.getIO().readObject(aData);
                                Dest=aData.getMixedArray(PdfDictionary.Dest);
                            }
                        }
                    }
                   
                    String filename = aData.getTextStreamValue(PdfDictionary.F);

                    if(filename==null){
                        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 ./
                        int slashIndex = filename.indexOf(":/");
                        if((slashIndex==-1 || slashIndex>1) && !filename.startsWith("/")){
                            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){
                       
                       
                        //get pageRef as number of ref
                        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){
                            String newRef=decode_pdf.getIO().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
                    //<</Type/Annot/Subtype/Link/Border[0 0 0]/Rect[56 715.1 137.1 728.9]/A<</Type/Action/S/GoToR/F(test1.pdf)>>
                    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)
                                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)
                                        float x=Dest.getNextValueAsFloat();
                                        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
                                       
                                        //and then scroll to location
                                        float top=Dest.getNextValueAsFloat();
                                       
                                        //create Rectangle to scroll to
                                        position=new Rectangle(10,(int)top,10,10);
                                       
                                        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 /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.
                                         */
                                       
                                        /* [ 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
                                         */
                                    default:
                                       
                                }
                               
                                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.
                           
                            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 {
                                actionFactory.showMessageDialog("The file specified " + filename + " Does Not Exist!");
                            }
                            break;
                        default:
                    }
                } else
                    actionFactory.setCursor(eventType);
            }
           
            return page;
        }

  private void additionalAction_Print(int eventType) {
    if (showMethods)
      System.out.println("DefaultActionHandler.additionalAction_Print()");

    if (eventType == MOUSERELEASED)
      actionFactory.print();

  }

  /**
   * display signature details in popup frame
   * @param formObj
   * @param eventType
   */
  private void additionalAction_Signature(FormObject formObj, int eventType) {
    if (showMethods)
        System.out.println("DefaultActionHandler.additionalAction_Signature()");

    if (eventType == MOUSECLICKED) {

            PdfObject sigObject=formObj.getDictionary(PdfDictionary.V);//.getDictionary(PdfDictionary.Sig);

      if (sigObject == null)
        return;

      actionFactory.showSig(sigObject);

    } else
      actionFactory.setCursor(eventType);
  }

  /**
   * 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
   */
  public void changeTo(String file, int page, Object location, Integer type,boolean storeView) {
   
    if (showMethods)
      System.out.println("DefaultActionHandler.changeTo()"+file);

    // open file 'file'
    if (file != null) {
      try {

                //we are working at '2 levels'. We have the Viewer and the
                //instance of PdfDecoder. If we only open in PDFDecoder, GUI thinks it is
                //still the original file, which causes issues. So we have to change file
                //at the viewer level.

                 //<start-adobe><start-thin>
                //added to check the forms save flag to tell the user how to save the now changed pdf file

                org.jpedal.examples.simpleviewer.gui.SwingGUI gui = ((org.jpedal.examples.simpleviewer.gui.SwingGUI) decode_pdf.getExternalHandler(Options.SwingContainer));
                if(gui!=null){
                    gui.stopThumbnails();
                   // gui.checkformSavedMessage();
                }

                if(file.startsWith("http://") || file.startsWith("ftp://") || file.startsWith("https:")){
                    if(gui!=null)
                        gui.currentCommands.executeCommand(Commands.OPENURL,new Object[]{file});
                    else
              decode_pdf.openPdfFileFromURL(file, true);
        }else {
                    if(gui!=null)
                        gui.currentCommands.executeCommand(Commands.OPENFILE,new Object[]{file});
                    else
          decode_pdf.openPdfFile(file);
        }

                //<end-thin><end-adobe>

        if(page==-1)
          page=1;
      } catch (Exception e) {
      }
    }

    // change to 'page'
    if (page != -1) {
      //we should use +1 as we reference pages from 1.
      if(decode_pdf.getPageCount()!=1 && decode_pdf.getlastPageDecoded()!=page){
        if (page > 0 && page < decode_pdf.getPageCount()+1) {
          try {
            decode_pdf.decodePage(page);

                        //<start-adobe><start-thin>
                        //update page number
                        if (page != -1){
                            org.jpedal.gui.GUIFactory customSwingHandle =(org.jpedal.gui.GUIFactory)decode_pdf.getExternalHandler(Options.MultiPageUpdate);
                            if(customSwingHandle!=null)
                                customSwingHandle.setPage(page);
                        }
                        //<end-thin><end-adobe>

          } catch (Exception e) {
            e.printStackTrace();
          }
 
          /** reset as rotation may change! */
          decode_pdf.setPageParameters(-1, page);

        }
      }
    }

    //<start-adobe><start-thin>
    if(type!=null){
      //now available via callback
      Object swingGUI = this.decode_pdf.getExternalHandler(org.jpedal.external.Options.SwingContainer);

          /**
           * Display the page designated by page, with its contents magnified just enough to
           * fit the entire page 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 page within the window in the other
           * dimension.
           */
            //set to fit - please use full paths (we do not want in imports as it will break Adobe version)
            if(swingGUI!=null){
              if(type <0){
                //set scaling box to 0 index, which is scale to window
                ((org.jpedal.examples.simpleviewer.gui.SwingGUI)swingGUI).setSelectedComboIndex(org.jpedal.examples.simpleviewer.Commands.SCALING, type +3);
              }else {
                //set scaling box to actual scaling value
                ((org.jpedal.examples.simpleviewer.gui.SwingGUI)swingGUI).setSelectedComboItem(org.jpedal.examples.simpleviewer.Commands.SCALING,type.toString());
              }
            }
    }
   
    //scroll to 'location'
        if (location != null) {
            Display pages=(org.jpedal.SingleDisplay) decode_pdf.getExternalHandler(org.jpedal.external.Options.Display);

            double scaling = decode_pdf.getScaling();
            double x = ((decode_pdf.getPdfPageData().getMediaBoxWidth(page) - ((Rectangle)location).getX())*scaling) + pages.getXCordForPage(page);
            double y = ((decode_pdf.getPdfPageData().getCropBoxHeight(page) - ((Rectangle)location).getY())*scaling) + pages.getYCordForPage(page);

            location = new Rectangle((int)x, (int)y, (int)decode_pdf.getVisibleRect().getWidth(), (int)decode_pdf.getVisibleRect().getHeight());

            decode_pdf.scrollRectToVisible((Rectangle) location);
        }
       
    SwingGUI swingGUI=((SwingGUI)decode_pdf.getExternalHandler(Options.SwingContainer));
    if(swingGUI!=null){
      ((org.jpedal.examples.simpleviewer.gui.SwingGUI)swingGUI).zoom(true);
 
      if(storeView)
        swingGUI.currentCommands.executeCommand(Commands.ADDVIEW,new Object[]{page,location,type});
    }
    //<end-thin><end-adobe>

        decode_pdf.repaint();
    }

    public PdfDecoder getPDFDecoder() {
        return decode_pdf;
    }

  /**
   * E action when cursor enters active area
   */
  public void E(Object e, FormObject formObj) {
    if (showMethods)
      System.out.println("DefaultActionHandler.E()");
   
  }

  /**
   * X action when cursor exits active area
   */
  public void X(Object e, FormObject formObj) {
    if (showMethods)
      System.out.println("DefaultActionHandler.X()");

  }

  /**
   * D action when cursor button pressed inside active area
   */
  public void D(Object e, FormObject formObj) {
    if (showMethods)
      System.out.println("DefaultActionHandler.D()");

  }

  /**
   * U action when cursor button released inside active area
   */
  public void U(Object e, FormObject formObj) {
    if (showMethods)
      System.out.println("DefaultActionHandler.U()");

  }

  /**
   * Fo action on input focus
   */
  public void Fo(Object e, FormObject formObj) {     //TODO called with focus gained
    if (showMethods)
      System.out.println("DefaultActionHandler.Fo()");


    // Scan through the fields and change any that have changed
    acrorend.updateChangedForms();
  }

  /**
   * Bl action when input focus lost, blur
   */
  public void Bl(Object e, FormObject formObj) { // TODO called by focus lost
    if (showMethods)
      System.out.println("DefaultActionHandler.Bl()");

  }

  /**
   * O called when a page is opened
   */
  public void O(PdfObject pdfObject,int type) {
    if (showMethods)
      System.out.println("DefaultActionHandler.O()");


        //theoretically we will need it to update the forms, or to make sure they are updated.
        //the proxy code it may not need to be called but i thin we may have dropped that.
       
        //Scan through the fields and change any that have changed
    acrorend.updateChangedForms();
  }

  /**
   * PO action when page containing is opened,
   * actions O of pages AA dic, and OpenAction in document catalog should be done first
   */
  public void PO(PdfObject pdfObject,int type) {
    if (showMethods)
      System.out.println("DefaultActionHandler.PO()");

  }

  /**
   * PC action when page is closed, action C from pages AA dic follows this
   */
  public void PC(PdfObject pdfObject,int type) {
    if (showMethods)
      System.out.println("DefaultActionHandler.PC()");
   
  }

  /**
   * PV action on viewing containing page
   */
  public void PV(PdfObject pdfObject,int type) {
    if (showMethods)
      System.out.println("DefaultActionHandler.PV()");


    // Scan through the fields and change any that have changed
    acrorend.updateChangedForms();
  }

  /**
   * PI action when page no longer visible in viewer
   */
  public void PI(PdfObject pdfObject,int type) {
    if (showMethods)
      System.out.println("DefaultActionHandler.PI()");

  }

  /**
   * 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)
   */
  public int K(Object ex, FormObject formObj, int actionID) {
    if (showMethods)
      System.out.println("DefaultActionHandler.K()");

    @SuppressWarnings("UnusedAssignment") int result=-1;

   
    return result;
  }

  /**
   * F the display formatting of the field (e.g 2 decimal places) [javascript]
   */
  public void F(FormObject formObj) {
    if (showMethods)
      System.out.println("DefaultActionHandler.F()");

  }

  /**
   * V action when fields value is changed [javascript], validate
   */
  public void V(Object ex, FormObject formObj, int actionID) {
    if (showMethods)
      System.out.println("DefaultActionHandler.V()");
   
    //set this fields value within the FormObject so javascript actions are correct
    //String fieldRef = formObj.getPDFRef();
    String fieldRef = formObj.getObjectRefAsString();
    acrorend.getCompData().storeDisplayValue(fieldRef);

  }

  Map Ccalled = new HashMap();
  /**
   * C action when another field changes (recalculate this field) [javascript]
   * <p/>
   * NOT actually called as called from other other objects but here for completeness
   */
  public void C(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");
   
    Ccalled.remove(formObj.getObjectRefAsString());
  }

  /**
   * goes through the map and adds the required data to the hideMap and returns it
   */
  private static void getHideMap(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) {
      String fieldList = aData.getTextStreamValue(PdfDictionary.T);
      if(fieldList!=null){
        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;
      }
    }
   
    boolean hideFlag = aData.getBoolean(PdfDictionary.H);
   
    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) {
      PdfObject nextDic = aData.getDictionary(PdfDictionary.Next);
      getHideMap(nextDic, fieldToHide);
    }
  }

  public PdfLayerList getLayerHandler() {
    return (PdfLayerList)decode_pdf.getJPedalObject(PdfDictionary.Layer);

  }

  //<start-adobe><start-thin>
  public void setMouseHandler(SwingMouseListener swingMouseHandler) {
    this.swingMouseHandler = swingMouseHandler;
  }
 
  public void updateCordsFromFormComponent(MouseEvent e, boolean mouseClicked) {
   
    if(swingMouseHandler!=null){
      swingMouseHandler.updateCordsFromFormComponent(e);
      swingMouseHandler.checkLinks(mouseClicked,decode_pdf.getIO());
    }
  }

    public SwingMouseListener getSwingMouseHandler() {
        return swingMouseHandler;
    }
    //<end-thin><end-adobe>
}
TOP

Related Classes of org.jpedal.objects.acroforms.actions.DefaultActionHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.