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