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_widgethandler.h"
      8 
      9 #include <memory>
     10 #include <vector>
     11 
     12 #include "core/fpdfapi/page/cpdf_page.h"
     13 #include "core/fpdfapi/parser/cpdf_document.h"
     14 #include "core/fpdfdoc/cpdf_interform.h"
     15 #include "fpdfsdk/cpdfsdk_annot.h"
     16 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
     17 #include "fpdfsdk/cpdfsdk_interform.h"
     18 #include "fpdfsdk/cpdfsdk_pageview.h"
     19 #include "fpdfsdk/cpdfsdk_widget.h"
     20 #include "fpdfsdk/formfiller/cffl_formfiller.h"
     21 
     22 #ifdef PDF_ENABLE_XFA
     23 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
     24 #endif  // PDF_ENABLE_XFA
     25 
     26 CPDFSDK_WidgetHandler::CPDFSDK_WidgetHandler(
     27     CPDFSDK_FormFillEnvironment* pFormFillEnv)
     28     : m_pFormFillEnv(pFormFillEnv),
     29       m_pFormFiller(pFormFillEnv->GetInteractiveFormFiller()) {}
     30 
     31 CPDFSDK_WidgetHandler::~CPDFSDK_WidgetHandler() {}
     32 
     33 bool CPDFSDK_WidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
     34   ASSERT(pAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET);
     35   if (pAnnot->IsSignatureWidget())
     36     return false;
     37 
     38   CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
     39   if (!pWidget->IsVisible())
     40     return false;
     41 
     42   int nFieldFlags = pWidget->GetFieldFlags();
     43   if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
     44     return false;
     45 
     46   if (pWidget->GetFieldType() == FormFieldType::kPushButton)
     47     return true;
     48 
     49   CPDF_Page* pPage = pWidget->GetPDFPage();
     50   uint32_t dwPermissions = pPage->m_pDocument->GetUserPermissions();
     51   return (dwPermissions & FPDFPERM_FILL_FORM) ||
     52          (dwPermissions & FPDFPERM_ANNOT_FORM);
     53 }
     54 
     55 CPDFSDK_Annot* CPDFSDK_WidgetHandler::NewAnnot(CPDF_Annot* pAnnot,
     56                                                CPDFSDK_PageView* pPage) {
     57   CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
     58   CPDF_FormControl* pCtrl = CPDFSDK_Widget::GetFormControl(
     59       pInterForm->GetInterForm(), pAnnot->GetAnnotDict());
     60   if (!pCtrl)
     61     return nullptr;
     62 
     63   CPDFSDK_Widget* pWidget = new CPDFSDK_Widget(pAnnot, pPage, pInterForm);
     64   pInterForm->AddMap(pCtrl, pWidget);
     65   CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
     66   if (pPDFInterForm && pPDFInterForm->NeedConstructAP())
     67     pWidget->ResetAppearance(nullptr, false);
     68 
     69   return pWidget;
     70 }
     71 
     72 #ifdef PDF_ENABLE_XFA
     73 CPDFSDK_Annot* CPDFSDK_WidgetHandler::NewAnnot(CXFA_FFWidget* hWidget,
     74                                                CPDFSDK_PageView* pPage) {
     75   return nullptr;
     76 }
     77 #endif  // PDF_ENABLE_XFA
     78 
     79 void CPDFSDK_WidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
     80   ASSERT(pAnnot);
     81 
     82   if (m_pFormFiller)
     83     m_pFormFiller->OnDelete(pAnnot);
     84 
     85   std::unique_ptr<CPDFSDK_Widget> pWidget(static_cast<CPDFSDK_Widget*>(pAnnot));
     86   CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
     87   CPDF_FormControl* pControl = pWidget->GetFormControl();
     88   pInterForm->RemoveMap(pControl);
     89 }
     90 
     91 void CPDFSDK_WidgetHandler::OnDraw(CPDFSDK_PageView* pPageView,
     92                                    CPDFSDK_Annot* pAnnot,
     93                                    CFX_RenderDevice* pDevice,
     94                                    CFX_Matrix* pUser2Device,
     95                                    bool bDrawAnnots) {
     96   if (pAnnot->IsSignatureWidget()) {
     97     static_cast<CPDFSDK_BAAnnot*>(pAnnot)->DrawAppearance(
     98         pDevice, *pUser2Device, CPDF_Annot::Normal, nullptr);
     99   } else {
    100     if (m_pFormFiller)
    101       m_pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device);
    102   }
    103 }
    104 
    105 void CPDFSDK_WidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
    106                                          CPDFSDK_Annot::ObservedPtr* pAnnot,
    107                                          uint32_t nFlag) {
    108   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    109     m_pFormFiller->OnMouseEnter(pPageView, pAnnot, nFlag);
    110 }
    111 
    112 void CPDFSDK_WidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
    113                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
    114                                         uint32_t nFlag) {
    115   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    116     m_pFormFiller->OnMouseExit(pPageView, pAnnot, nFlag);
    117 }
    118 
    119 bool CPDFSDK_WidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
    120                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
    121                                           uint32_t nFlags,
    122                                           const CFX_PointF& point) {
    123   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    124     return m_pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
    125 
    126   return false;
    127 }
    128 
    129 bool CPDFSDK_WidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
    130                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
    131                                         uint32_t nFlags,
    132                                         const CFX_PointF& point) {
    133   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    134     return m_pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
    135 
    136   return false;
    137 }
    138 
    139 bool CPDFSDK_WidgetHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
    140                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
    141                                             uint32_t nFlags,
    142                                             const CFX_PointF& point) {
    143   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    144     return m_pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
    145 
    146   return false;
    147 }
    148 
    149 bool CPDFSDK_WidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
    150                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
    151                                         uint32_t nFlags,
    152                                         const CFX_PointF& point) {
    153   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    154     return m_pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
    155 
    156   return false;
    157 }
    158 
    159 bool CPDFSDK_WidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
    160                                          CPDFSDK_Annot::ObservedPtr* pAnnot,
    161                                          uint32_t nFlags,
    162                                          short zDelta,
    163                                          const CFX_PointF& point) {
    164   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    165     return m_pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta,
    166                                        point);
    167 
    168   return false;
    169 }
    170 
    171 bool CPDFSDK_WidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
    172                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
    173                                           uint32_t nFlags,
    174                                           const CFX_PointF& point) {
    175   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    176     return m_pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
    177 
    178   return false;
    179 }
    180 
    181 bool CPDFSDK_WidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
    182                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
    183                                         uint32_t nFlags,
    184                                         const CFX_PointF& point) {
    185   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    186     return m_pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
    187 
    188   return false;
    189 }
    190 
    191 bool CPDFSDK_WidgetHandler::OnRButtonDblClk(CPDFSDK_PageView* pPageView,
    192                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
    193                                             uint32_t nFlags,
    194                                             const CFX_PointF& point) {
    195   return false;
    196 }
    197 
    198 bool CPDFSDK_WidgetHandler::OnChar(CPDFSDK_Annot* pAnnot,
    199                                    uint32_t nChar,
    200                                    uint32_t nFlags) {
    201   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
    202     return m_pFormFiller->OnChar(pAnnot, nChar, nFlags);
    203 
    204   return false;
    205 }
    206 
    207 bool CPDFSDK_WidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
    208                                       int nKeyCode,
    209                                       int nFlag) {
    210   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
    211     return m_pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlag);
    212 
    213   return false;
    214 }
    215 
    216 bool CPDFSDK_WidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
    217                                     int nKeyCode,
    218                                     int nFlag) {
    219   return false;
    220 }
    221 
    222 void CPDFSDK_WidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) {
    223   if (pAnnot->IsSignatureWidget())
    224     return;
    225 
    226   CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
    227   if (!pWidget->IsAppearanceValid())
    228     pWidget->ResetAppearance(nullptr, false);
    229 
    230   FormFieldType fieldType = pWidget->GetFieldType();
    231   if (fieldType == FormFieldType::kTextField ||
    232       fieldType == FormFieldType::kComboBox) {
    233     bool bFormatted = false;
    234     CPDFSDK_Annot::ObservedPtr pObserved(pWidget);
    235     WideString sValue = pWidget->OnFormat(bFormatted);
    236     if (!pObserved)
    237       return;
    238 
    239     if (bFormatted && fieldType == FormFieldType::kComboBox)
    240       pWidget->ResetAppearance(&sValue, false);
    241   }
    242 
    243 #ifdef PDF_ENABLE_XFA
    244   CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
    245   CPDFXFA_Context* pContext = pPageView->GetFormFillEnv()->GetXFAContext();
    246   if (pContext->GetFormType() == FormType::kXFAForeground) {
    247     if (!pWidget->IsAppearanceValid() && !pWidget->GetValue().IsEmpty())
    248       pWidget->ResetAppearance(false);
    249   }
    250 #endif  // PDF_ENABLE_XFA
    251 }
    252 
    253 bool CPDFSDK_WidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
    254                                        uint32_t nFlag) {
    255   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    256     return m_pFormFiller->OnSetFocus(pAnnot, nFlag);
    257 
    258   return true;
    259 }
    260 
    261 bool CPDFSDK_WidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
    262                                         uint32_t nFlag) {
    263   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
    264     return m_pFormFiller->OnKillFocus(pAnnot, nFlag);
    265 
    266   return true;
    267 }
    268 
    269 #ifdef PDF_ENABLE_XFA
    270 bool CPDFSDK_WidgetHandler::OnXFAChangedFocus(
    271     CPDFSDK_Annot::ObservedPtr* pOldAnnot,
    272     CPDFSDK_Annot::ObservedPtr* pNewAnnot) {
    273   return true;
    274 }
    275 #endif  // PDF_ENABLE_XFA
    276 
    277 CFX_FloatRect CPDFSDK_WidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
    278                                                  CPDFSDK_Annot* pAnnot) {
    279   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
    280     return CFX_FloatRect(m_pFormFiller->GetViewBBox(pPageView, pAnnot));
    281   return CFX_FloatRect();
    282 }
    283 
    284 WideString CPDFSDK_WidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) {
    285   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
    286     return m_pFormFiller->GetSelectedText(pAnnot);
    287 
    288   return WideString();
    289 }
    290 
    291 void CPDFSDK_WidgetHandler::ReplaceSelection(CPDFSDK_Annot* pAnnot,
    292                                              const WideString& text) {
    293   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
    294     m_pFormFiller->ReplaceSelection(pAnnot, text);
    295 }
    296 
    297 bool CPDFSDK_WidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
    298                                     CPDFSDK_Annot* pAnnot,
    299                                     const CFX_PointF& point) {
    300   ASSERT(pPageView);
    301   ASSERT(pAnnot);
    302   return GetViewBBox(pPageView, pAnnot).Contains(point);
    303 }
    304