Home | History | Annotate | Download | only in fpdfsdk
      1 // Copyright 2016 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "fpdfsdk/cpdfsdk_annothandlermgr.h"
      8 
      9 #include "core/fpdfapi/parser/cpdf_number.h"
     10 #include "core/fpdfapi/parser/cpdf_string.h"
     11 #include "core/fpdfdoc/cpdf_annot.h"
     12 #include "fpdfsdk/cba_annotiterator.h"
     13 #include "fpdfsdk/cpdfsdk_annot.h"
     14 #include "fpdfsdk/cpdfsdk_baannot.h"
     15 #include "fpdfsdk/cpdfsdk_baannothandler.h"
     16 #include "fpdfsdk/cpdfsdk_datetime.h"
     17 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
     18 #include "fpdfsdk/cpdfsdk_pageview.h"
     19 #include "fpdfsdk/cpdfsdk_widgethandler.h"
     20 
     21 #ifdef PDF_ENABLE_XFA
     22 #include "fpdfsdk/cpdfsdk_xfawidgethandler.h"
     23 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
     24 #include "xfa/fxfa/xfa_ffpageview.h"
     25 #include "xfa/fxfa/xfa_ffwidget.h"
     26 #endif  // PDF_ENABLE_XFA
     27 
     28 CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(
     29     CPDFSDK_FormFillEnvironment* pFormFillEnv)
     30     : m_pBAAnnotHandler(new CPDFSDK_BAAnnotHandler()),
     31       m_pWidgetHandler(new CPDFSDK_WidgetHandler(pFormFillEnv)),
     32 #ifdef PDF_ENABLE_XFA
     33       m_pXFAWidgetHandler(new CPDFSDK_XFAWidgetHandler(pFormFillEnv)),
     34 #endif  // PDF_ENABLE_XFA
     35       m_pFormFillEnv(pFormFillEnv) {
     36   m_pWidgetHandler->SetFormFiller(m_pFormFillEnv->GetInteractiveFormFiller());
     37 }
     38 
     39 CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() {}
     40 
     41 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot* pAnnot,
     42                                                  CPDFSDK_PageView* pPageView) {
     43   ASSERT(pPageView);
     44   return GetAnnotHandler(pAnnot->GetSubtype())->NewAnnot(pAnnot, pPageView);
     45 }
     46 
     47 #ifdef PDF_ENABLE_XFA
     48 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CXFA_FFWidget* pAnnot,
     49                                                  CPDFSDK_PageView* pPageView) {
     50   ASSERT(pAnnot);
     51   ASSERT(pPageView);
     52 
     53   return GetAnnotHandler(CPDF_Annot::Subtype::XFAWIDGET)
     54       ->NewAnnot(pAnnot, pPageView);
     55 }
     56 #endif  // PDF_ENABLE_XFA
     57 
     58 void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
     59   IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
     60   pAnnotHandler->ReleaseAnnot(pAnnot);
     61 }
     62 
     63 void CPDFSDK_AnnotHandlerMgr::Annot_OnCreate(CPDFSDK_Annot* pAnnot) {
     64   CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
     65 
     66   CPDFSDK_DateTime curTime;
     67   pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
     68       "M", curTime.ToPDFDateTimeString(), false);
     69   pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F", 0);
     70 }
     71 
     72 void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) {
     73   ASSERT(pAnnot);
     74   GetAnnotHandler(pAnnot)->OnLoad(pAnnot);
     75 }
     76 
     77 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
     78     CPDFSDK_Annot* pAnnot) const {
     79   return GetAnnotHandler(pAnnot->GetAnnotSubtype());
     80 }
     81 
     82 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
     83     CPDF_Annot::Subtype nAnnotSubtype) const {
     84   if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET)
     85     return m_pWidgetHandler.get();
     86 
     87 #ifdef PDF_ENABLE_XFA
     88   if (nAnnotSubtype == CPDF_Annot::Subtype::XFAWIDGET)
     89     return m_pXFAWidgetHandler.get();
     90 #endif  // PDF_ENABLE_XFA
     91 
     92   return m_pBAAnnotHandler.get();
     93 }
     94 
     95 void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView,
     96                                            CPDFSDK_Annot* pAnnot,
     97                                            CFX_RenderDevice* pDevice,
     98                                            CFX_Matrix* pUser2Device,
     99                                            bool bDrawAnnots) {
    100   ASSERT(pAnnot);
    101   GetAnnotHandler(pAnnot)->OnDraw(pPageView, pAnnot, pDevice, pUser2Device,
    102                                   bDrawAnnots);
    103 }
    104 
    105 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown(
    106     CPDFSDK_PageView* pPageView,
    107     CPDFSDK_Annot::ObservedPtr* pAnnot,
    108     uint32_t nFlags,
    109     const CFX_PointF& point) {
    110   ASSERT(*pAnnot);
    111   return GetAnnotHandler(pAnnot->Get())
    112       ->OnLButtonDown(pPageView, pAnnot, nFlags, point);
    113 }
    114 
    115 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp(
    116     CPDFSDK_PageView* pPageView,
    117     CPDFSDK_Annot::ObservedPtr* pAnnot,
    118     uint32_t nFlags,
    119     const CFX_PointF& point) {
    120   ASSERT(*pAnnot);
    121   return GetAnnotHandler(pAnnot->Get())
    122       ->OnLButtonUp(pPageView, pAnnot, nFlags, point);
    123 }
    124 
    125 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk(
    126     CPDFSDK_PageView* pPageView,
    127     CPDFSDK_Annot::ObservedPtr* pAnnot,
    128     uint32_t nFlags,
    129     const CFX_PointF& point) {
    130   ASSERT(*pAnnot);
    131   return GetAnnotHandler(pAnnot->Get())
    132       ->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
    133 }
    134 
    135 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove(
    136     CPDFSDK_PageView* pPageView,
    137     CPDFSDK_Annot::ObservedPtr* pAnnot,
    138     uint32_t nFlags,
    139     const CFX_PointF& point) {
    140   ASSERT(*pAnnot);
    141   return GetAnnotHandler(pAnnot->Get())
    142       ->OnMouseMove(pPageView, pAnnot, nFlags, point);
    143 }
    144 
    145 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel(
    146     CPDFSDK_PageView* pPageView,
    147     CPDFSDK_Annot::ObservedPtr* pAnnot,
    148     uint32_t nFlags,
    149     short zDelta,
    150     const CFX_PointF& point) {
    151   ASSERT(*pAnnot);
    152   return GetAnnotHandler(pAnnot->Get())
    153       ->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
    154 }
    155 
    156 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown(
    157     CPDFSDK_PageView* pPageView,
    158     CPDFSDK_Annot::ObservedPtr* pAnnot,
    159     uint32_t nFlags,
    160     const CFX_PointF& point) {
    161   ASSERT(*pAnnot);
    162   return GetAnnotHandler(pAnnot->Get())
    163       ->OnRButtonDown(pPageView, pAnnot, nFlags, point);
    164 }
    165 
    166 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp(
    167     CPDFSDK_PageView* pPageView,
    168     CPDFSDK_Annot::ObservedPtr* pAnnot,
    169     uint32_t nFlags,
    170     const CFX_PointF& point) {
    171   ASSERT(*pAnnot);
    172   return GetAnnotHandler(pAnnot->Get())
    173       ->OnRButtonUp(pPageView, pAnnot, nFlags, point);
    174 }
    175 
    176 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseEnter(
    177     CPDFSDK_PageView* pPageView,
    178     CPDFSDK_Annot::ObservedPtr* pAnnot,
    179     uint32_t nFlag) {
    180   ASSERT(*pAnnot);
    181   GetAnnotHandler(pAnnot->Get())->OnMouseEnter(pPageView, pAnnot, nFlag);
    182 }
    183 
    184 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseExit(
    185     CPDFSDK_PageView* pPageView,
    186     CPDFSDK_Annot::ObservedPtr* pAnnot,
    187     uint32_t nFlag) {
    188   ASSERT(*pAnnot);
    189   GetAnnotHandler(pAnnot->Get())->OnMouseExit(pPageView, pAnnot, nFlag);
    190 }
    191 
    192 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChar(CPDFSDK_Annot* pAnnot,
    193                                            uint32_t nChar,
    194                                            uint32_t nFlags) {
    195   return GetAnnotHandler(pAnnot)->OnChar(pAnnot, nChar, nFlags);
    196 }
    197 
    198 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyDown(CPDFSDK_Annot* pAnnot,
    199                                               int nKeyCode,
    200                                               int nFlag) {
    201   if (m_pFormFillEnv->IsCTRLKeyDown(nFlag) ||
    202       m_pFormFillEnv->IsALTKeyDown(nFlag)) {
    203     return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
    204   }
    205 
    206   CPDFSDK_PageView* pPage = pAnnot->GetPageView();
    207   CPDFSDK_Annot* pFocusAnnot = pPage->GetFocusAnnot();
    208   if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab)) {
    209     CPDFSDK_Annot::ObservedPtr pNext(
    210         GetNextAnnot(pFocusAnnot, !m_pFormFillEnv->IsSHIFTKeyDown(nFlag)));
    211     if (pNext && pNext.Get() != pFocusAnnot) {
    212       pPage->GetFormFillEnv()->SetFocusAnnot(&pNext);
    213       return true;
    214     }
    215   }
    216 
    217   return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
    218 }
    219 
    220 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyUp(CPDFSDK_Annot* pAnnot,
    221                                             int nKeyCode,
    222                                             int nFlag) {
    223   return false;
    224 }
    225 
    226 bool CPDFSDK_AnnotHandlerMgr::Annot_OnSetFocus(
    227     CPDFSDK_Annot::ObservedPtr* pAnnot,
    228     uint32_t nFlag) {
    229   ASSERT(*pAnnot);
    230   return GetAnnotHandler(pAnnot->Get())->OnSetFocus(pAnnot, nFlag);
    231 }
    232 
    233 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(
    234     CPDFSDK_Annot::ObservedPtr* pAnnot,
    235     uint32_t nFlag) {
    236   ASSERT(*pAnnot);
    237   return GetAnnotHandler(pAnnot->Get())->OnKillFocus(pAnnot, nFlag);
    238 }
    239 
    240 #ifdef PDF_ENABLE_XFA
    241 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChangeFocus(
    242     CPDFSDK_Annot::ObservedPtr* pSetAnnot,
    243     CPDFSDK_Annot::ObservedPtr* pKillAnnot) {
    244   bool bXFA = (*pSetAnnot && (*pSetAnnot)->GetXFAWidget()) ||
    245               (*pKillAnnot && (*pKillAnnot)->GetXFAWidget());
    246 
    247   if (bXFA) {
    248     if (IPDFSDK_AnnotHandler* pXFAAnnotHandler =
    249             GetAnnotHandler(CPDF_Annot::Subtype::XFAWIDGET))
    250       return pXFAAnnotHandler->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
    251   }
    252 
    253   return true;
    254 }
    255 #endif  // PDF_ENABLE_XFA
    256 
    257 CFX_FloatRect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(
    258     CPDFSDK_PageView* pPageView,
    259     CPDFSDK_Annot* pAnnot) {
    260   ASSERT(pAnnot);
    261   return GetAnnotHandler(pAnnot)->GetViewBBox(pPageView, pAnnot);
    262 }
    263 
    264 bool CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView* pPageView,
    265                                               CPDFSDK_Annot* pAnnot,
    266                                               const CFX_PointF& point) {
    267   ASSERT(pAnnot);
    268   IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
    269   if (pAnnotHandler->CanAnswer(pAnnot))
    270     return pAnnotHandler->HitTest(pPageView, pAnnot, point);
    271 
    272   return false;
    273 }
    274 
    275 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,
    276                                                      bool bNext) {
    277 #ifdef PDF_ENABLE_XFA
    278   CPDFSDK_PageView* pPageView = pSDKAnnot->GetPageView();
    279   CPDFXFA_Page* pPage = pPageView->GetPDFXFAPage();
    280   if (!pPage)
    281     return nullptr;
    282   if (pPage->GetPDFPage()) {  // for pdf annots.
    283     CBA_AnnotIterator ai(pSDKAnnot->GetPageView(),
    284                          pSDKAnnot->GetAnnotSubtype());
    285     CPDFSDK_Annot* pNext =
    286         bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
    287     return pNext;
    288   }
    289   // for xfa annots
    290   std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator(
    291       pPage->GetXFAPageView()->CreateWidgetIterator(
    292           XFA_TRAVERSEWAY_Tranvalse, XFA_WidgetStatus_Visible |
    293                                          XFA_WidgetStatus_Viewable |
    294                                          XFA_WidgetStatus_Focused));
    295   if (!pWidgetIterator)
    296     return nullptr;
    297   if (pWidgetIterator->GetCurrentWidget() != pSDKAnnot->GetXFAWidget())
    298     pWidgetIterator->SetCurrentWidget(pSDKAnnot->GetXFAWidget());
    299   CXFA_FFWidget* hNextFocus =
    300       bNext ? pWidgetIterator->MoveToNext() : pWidgetIterator->MoveToPrevious();
    301   if (!hNextFocus && pSDKAnnot)
    302     hNextFocus = pWidgetIterator->MoveToFirst();
    303 
    304   return pPageView->GetAnnotByXFAWidget(hNextFocus);
    305 #else   // PDF_ENABLE_XFA
    306   CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), CPDF_Annot::Subtype::WIDGET);
    307   return bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
    308 #endif  // PDF_ENABLE_XFA
    309 }
    310