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