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_xfawidgethandler.h"
      8 
      9 #include "core/fpdfdoc/cpdf_interform.h"
     10 #include "fpdfsdk/cpdfsdk_annot.h"
     11 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
     12 #include "fpdfsdk/cpdfsdk_interform.h"
     13 #include "fpdfsdk/cpdfsdk_pageview.h"
     14 #include "fpdfsdk/cpdfsdk_xfawidget.h"
     15 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
     16 #include "xfa/fwl/cfwl_app.h"
     17 #include "xfa/fwl/fwl_widgethit.h"
     18 #include "xfa/fxfa/cxfa_ffdocview.h"
     19 #include "xfa/fxfa/cxfa_ffpageview.h"
     20 #include "xfa/fxfa/cxfa_ffwidget.h"
     21 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
     22 #include "xfa/fxfa/fxfa_basic.h"
     23 #include "xfa/fxfa/parser/cxfa_node.h"
     24 #include "xfa/fxgraphics/cxfa_graphics.h"
     25 
     26 CPDFSDK_XFAWidgetHandler::CPDFSDK_XFAWidgetHandler(
     27     CPDFSDK_FormFillEnvironment* pFormFillEnv)
     28     : m_pFormFillEnv(pFormFillEnv) {}
     29 
     30 CPDFSDK_XFAWidgetHandler::~CPDFSDK_XFAWidgetHandler() {}
     31 
     32 bool CPDFSDK_XFAWidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
     33   return !!pAnnot->GetXFAWidget();
     34 }
     35 
     36 CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CPDF_Annot* pAnnot,
     37                                                   CPDFSDK_PageView* pPage) {
     38   return nullptr;
     39 }
     40 
     41 CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CXFA_FFWidget* pAnnot,
     42                                                   CPDFSDK_PageView* pPage) {
     43   CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
     44   CPDFSDK_XFAWidget* pWidget = new CPDFSDK_XFAWidget(pAnnot, pPage, pInterForm);
     45   pInterForm->AddXFAMap(pAnnot, pWidget);
     46   return pWidget;
     47 }
     48 
     49 void CPDFSDK_XFAWidgetHandler::OnDraw(CPDFSDK_PageView* pPageView,
     50                                       CPDFSDK_Annot* pAnnot,
     51                                       CFX_RenderDevice* pDevice,
     52                                       CFX_Matrix* pUser2Device,
     53                                       bool bDrawAnnots) {
     54   ASSERT(pPageView);
     55   ASSERT(pAnnot);
     56 
     57   CXFA_Graphics gs(pDevice);
     58 
     59   CFX_Matrix mt = *pUser2Device;
     60   bool bIsHighlight = false;
     61   if (pPageView->GetFormFillEnv()->GetFocusAnnot() != pAnnot)
     62     bIsHighlight = true;
     63 
     64   GetXFAWidgetHandler(pAnnot)->RenderWidget(pAnnot->GetXFAWidget(), &gs, mt,
     65                                             bIsHighlight);
     66 
     67   // to do highlight and shadow
     68 }
     69 
     70 void CPDFSDK_XFAWidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) {}
     71 
     72 void CPDFSDK_XFAWidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
     73   CPDFSDK_XFAWidget* pWidget = reinterpret_cast<CPDFSDK_XFAWidget*>(pAnnot);
     74   CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
     75   pInterForm->RemoveXFAMap(pWidget->GetXFAWidget());
     76 
     77   delete pWidget;
     78 }
     79 
     80 CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
     81                                                     CPDFSDK_Annot* pAnnot) {
     82   ASSERT(pAnnot);
     83 
     84   CFX_RectF rcBBox;
     85   XFA_Element eType =
     86       pAnnot->GetXFAWidget()->GetNode()->GetWidgetAcc()->GetUIType();
     87   if (eType == XFA_Element::Signature)
     88     rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_Visible, true);
     89   else
     90     rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_None);
     91 
     92   CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
     93                          rcBBox.top + rcBBox.height);
     94   rcWidget.left -= 1.0f;
     95   rcWidget.right += 1.0f;
     96   rcWidget.bottom -= 1.0f;
     97   rcWidget.top += 1.0f;
     98 
     99   return rcWidget;
    100 }
    101 
    102 WideString CPDFSDK_XFAWidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) {
    103   if (!pAnnot)
    104     return WideString();
    105 
    106   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
    107   return pWidgetHandler->GetSelectedText(pAnnot->GetXFAWidget());
    108 }
    109 
    110 void CPDFSDK_XFAWidgetHandler::ReplaceSelection(CPDFSDK_Annot* pAnnot,
    111                                                 const WideString& text) {
    112   if (!pAnnot)
    113     return;
    114 
    115   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
    116   return pWidgetHandler->PasteText(pAnnot->GetXFAWidget(), text);
    117 }
    118 
    119 bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
    120                                        CPDFSDK_Annot* pAnnot,
    121                                        const CFX_PointF& point) {
    122   if (!pPageView || !pAnnot)
    123     return false;
    124 
    125   CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
    126   if (!pFormFillEnv)
    127     return false;
    128 
    129   CPDFXFA_Context* pContext = pFormFillEnv->GetXFAContext();
    130   if (!pContext)
    131     return false;
    132 
    133   CXFA_FFDocView* pDocView = pContext->GetXFADocView();
    134   if (!pDocView)
    135     return false;
    136 
    137   CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
    138   if (!pWidgetHandler)
    139     return false;
    140 
    141   FWL_WidgetHit dwHitTest =
    142       pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point);
    143   return dwHitTest != FWL_WidgetHit::Unknown;
    144 }
    145 
    146 void CPDFSDK_XFAWidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
    147                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
    148                                             uint32_t nFlag) {
    149   if (!pPageView || !(*pAnnot))
    150     return;
    151   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    152   pWidgetHandler->OnMouseEnter((*pAnnot)->GetXFAWidget());
    153 }
    154 
    155 void CPDFSDK_XFAWidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
    156                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
    157                                            uint32_t nFlag) {
    158   if (!pPageView || !(*pAnnot))
    159     return;
    160 
    161   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    162   pWidgetHandler->OnMouseExit((*pAnnot)->GetXFAWidget());
    163 }
    164 
    165 bool CPDFSDK_XFAWidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
    166                                              CPDFSDK_Annot::ObservedPtr* pAnnot,
    167                                              uint32_t nFlags,
    168                                              const CFX_PointF& point) {
    169   if (!pPageView || !(*pAnnot))
    170     return false;
    171 
    172   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    173   return pWidgetHandler->OnLButtonDown((*pAnnot)->GetXFAWidget(),
    174                                        GetFWLFlags(nFlags), point);
    175 }
    176 
    177 bool CPDFSDK_XFAWidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
    178                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
    179                                            uint32_t nFlags,
    180                                            const CFX_PointF& point) {
    181   if (!pPageView || !(*pAnnot))
    182     return false;
    183 
    184   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    185   return pWidgetHandler->OnLButtonUp((*pAnnot)->GetXFAWidget(),
    186                                      GetFWLFlags(nFlags), point);
    187 }
    188 
    189 bool CPDFSDK_XFAWidgetHandler::OnLButtonDblClk(
    190     CPDFSDK_PageView* pPageView,
    191     CPDFSDK_Annot::ObservedPtr* pAnnot,
    192     uint32_t nFlags,
    193     const CFX_PointF& point) {
    194   if (!pPageView || !(*pAnnot))
    195     return false;
    196 
    197   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    198   return pWidgetHandler->OnLButtonDblClk((*pAnnot)->GetXFAWidget(),
    199                                          GetFWLFlags(nFlags), point);
    200 }
    201 
    202 bool CPDFSDK_XFAWidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
    203                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
    204                                            uint32_t nFlags,
    205                                            const CFX_PointF& point) {
    206   if (!pPageView || !(*pAnnot))
    207     return false;
    208 
    209   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    210   return pWidgetHandler->OnMouseMove((*pAnnot)->GetXFAWidget(),
    211                                      GetFWLFlags(nFlags), point);
    212 }
    213 
    214 bool CPDFSDK_XFAWidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
    215                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
    216                                             uint32_t nFlags,
    217                                             short zDelta,
    218                                             const CFX_PointF& point) {
    219   if (!pPageView || !(*pAnnot))
    220     return false;
    221 
    222   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    223   return pWidgetHandler->OnMouseWheel((*pAnnot)->GetXFAWidget(),
    224                                       GetFWLFlags(nFlags), zDelta, point);
    225 }
    226 
    227 bool CPDFSDK_XFAWidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
    228                                              CPDFSDK_Annot::ObservedPtr* pAnnot,
    229                                              uint32_t nFlags,
    230                                              const CFX_PointF& point) {
    231   if (!pPageView || !(*pAnnot))
    232     return false;
    233 
    234   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    235   return pWidgetHandler->OnRButtonDown((*pAnnot)->GetXFAWidget(),
    236                                        GetFWLFlags(nFlags), point);
    237 }
    238 
    239 bool CPDFSDK_XFAWidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
    240                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
    241                                            uint32_t nFlags,
    242                                            const CFX_PointF& point) {
    243   if (!pPageView || !(*pAnnot))
    244     return false;
    245 
    246   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    247   return pWidgetHandler->OnRButtonUp((*pAnnot)->GetXFAWidget(),
    248                                      GetFWLFlags(nFlags), point);
    249 }
    250 
    251 bool CPDFSDK_XFAWidgetHandler::OnRButtonDblClk(
    252     CPDFSDK_PageView* pPageView,
    253     CPDFSDK_Annot::ObservedPtr* pAnnot,
    254     uint32_t nFlags,
    255     const CFX_PointF& point) {
    256   if (!pPageView || !(*pAnnot))
    257     return false;
    258 
    259   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
    260   return pWidgetHandler->OnRButtonDblClk((*pAnnot)->GetXFAWidget(),
    261                                          GetFWLFlags(nFlags), point);
    262 }
    263 
    264 bool CPDFSDK_XFAWidgetHandler::OnChar(CPDFSDK_Annot* pAnnot,
    265                                       uint32_t nChar,
    266                                       uint32_t nFlags) {
    267   if (!pAnnot)
    268     return false;
    269 
    270   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
    271   return pWidgetHandler->OnChar(pAnnot->GetXFAWidget(), nChar,
    272                                 GetFWLFlags(nFlags));
    273 }
    274 
    275 bool CPDFSDK_XFAWidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
    276                                          int nKeyCode,
    277                                          int nFlag) {
    278   if (!pAnnot)
    279     return false;
    280 
    281   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
    282   return pWidgetHandler->OnKeyDown(pAnnot->GetXFAWidget(), nKeyCode,
    283                                    GetFWLFlags(nFlag));
    284 }
    285 
    286 bool CPDFSDK_XFAWidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
    287                                        int nKeyCode,
    288                                        int nFlag) {
    289   if (!pAnnot)
    290     return false;
    291 
    292   CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
    293   return pWidgetHandler->OnKeyUp(pAnnot->GetXFAWidget(), nKeyCode,
    294                                  GetFWLFlags(nFlag));
    295 }
    296 
    297 bool CPDFSDK_XFAWidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
    298                                           uint32_t nFlag) {
    299   return true;
    300 }
    301 
    302 bool CPDFSDK_XFAWidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
    303                                            uint32_t nFlag) {
    304   return true;
    305 }
    306 
    307 bool CPDFSDK_XFAWidgetHandler::OnXFAChangedFocus(
    308     CPDFSDK_Annot::ObservedPtr* pOldAnnot,
    309     CPDFSDK_Annot::ObservedPtr* pNewAnnot) {
    310   CXFA_FFWidgetHandler* pWidgetHandler = nullptr;
    311   if (*pOldAnnot)
    312     pWidgetHandler = GetXFAWidgetHandler(pOldAnnot->Get());
    313   else if (*pNewAnnot)
    314     pWidgetHandler = GetXFAWidgetHandler(pNewAnnot->Get());
    315 
    316   if (!pWidgetHandler)
    317     return true;
    318 
    319   CXFA_FFWidget* hWidget = *pNewAnnot ? (*pNewAnnot)->GetXFAWidget() : nullptr;
    320   if (!hWidget)
    321     return true;
    322 
    323   CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
    324   if (!pXFAPageView)
    325     return true;
    326 
    327   bool bRet = pXFAPageView->GetDocView()->SetFocus(hWidget);
    328   if (pXFAPageView->GetDocView()->GetFocusWidget() == hWidget)
    329     bRet = true;
    330 
    331   return bRet;
    332 }
    333 
    334 CXFA_FFWidgetHandler* CPDFSDK_XFAWidgetHandler::GetXFAWidgetHandler(
    335     CPDFSDK_Annot* pAnnot) {
    336   if (!pAnnot)
    337     return nullptr;
    338 
    339   CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
    340   if (!pPageView)
    341     return nullptr;
    342 
    343   CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
    344   if (!pFormFillEnv)
    345     return nullptr;
    346 
    347   CPDFXFA_Context* pDoc = pFormFillEnv->GetXFAContext();
    348   if (!pDoc)
    349     return nullptr;
    350 
    351   CXFA_FFDocView* pDocView = pDoc->GetXFADocView();
    352   if (!pDocView)
    353     return nullptr;
    354 
    355   return pDocView->GetWidgetHandler();
    356 }
    357 
    358 uint32_t CPDFSDK_XFAWidgetHandler::GetFWLFlags(uint32_t dwFlag) {
    359   uint32_t dwFWLFlag = 0;
    360 
    361   if (dwFlag & FWL_EVENTFLAG_ControlKey)
    362     dwFWLFlag |= FWL_KEYFLAG_Ctrl;
    363   if (dwFlag & FWL_EVENTFLAG_LeftButtonDown)
    364     dwFWLFlag |= FWL_KEYFLAG_LButton;
    365   if (dwFlag & FWL_EVENTFLAG_MiddleButtonDown)
    366     dwFWLFlag |= FWL_KEYFLAG_MButton;
    367   if (dwFlag & FWL_EVENTFLAG_RightButtonDown)
    368     dwFWLFlag |= FWL_KEYFLAG_RButton;
    369   if (dwFlag & FWL_EVENTFLAG_ShiftKey)
    370     dwFWLFlag |= FWL_KEYFLAG_Shift;
    371   if (dwFlag & FWL_EVENTFLAG_AltKey)
    372     dwFWLFlag |= FWL_KEYFLAG_Alt;
    373 
    374   return dwFWLFlag;
    375 }
    376