Home | History | Annotate | Download | only in formfiller
      1 // Copyright 2014 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/include/formfiller/FFL_IFormFiller.h"
      8 
      9 #include "fpdfsdk/include/formfiller/FFL_CheckBox.h"
     10 #include "fpdfsdk/include/formfiller/FFL_ComboBox.h"
     11 #include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
     12 #include "fpdfsdk/include/formfiller/FFL_ListBox.h"
     13 #include "fpdfsdk/include/formfiller/FFL_PushButton.h"
     14 #include "fpdfsdk/include/formfiller/FFL_RadioButton.h"
     15 #include "fpdfsdk/include/formfiller/FFL_TextField.h"
     16 #include "fpdfsdk/include/fsdk_mgr.h"
     17 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
     18 
     19 #define FFL_MAXLISTBOXHEIGHT 140.0f
     20 
     21 CFFL_IFormFiller::CFFL_IFormFiller(CPDFDoc_Environment* pApp)
     22     : m_pApp(pApp), m_bNotifying(FALSE) {}
     23 
     24 CFFL_IFormFiller::~CFFL_IFormFiller() {
     25   for (auto& it : m_Maps)
     26     delete it.second;
     27   m_Maps.clear();
     28 }
     29 
     30 FX_BOOL CFFL_IFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView,
     31                                         CPDFSDK_Annot* pAnnot,
     32                                         CPDF_Point point) {
     33   CPDF_Rect rc = pAnnot->GetRect();
     34   if (rc.Contains(point.x, point.y))
     35     return TRUE;
     36   return FALSE;
     37 }
     38 
     39 FX_RECT CFFL_IFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
     40                                       CPDFSDK_Annot* pAnnot) {
     41   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
     42     return pFormFiller->GetViewBBox(pPageView, pAnnot);
     43 
     44   ASSERT(pPageView);
     45 
     46   CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
     47   CPDF_Rect rcAnnot;
     48   pPDFAnnot->GetRect(rcAnnot);
     49 
     50   CPDF_Rect rcWin = CPWL_Utils::InflateRect(rcAnnot, 1);
     51   return rcWin.GetOutterRect();
     52 }
     53 
     54 void CFFL_IFormFiller::OnDraw(CPDFSDK_PageView* pPageView,
     55                               CPDFSDK_Annot* pAnnot,
     56                               CFX_RenderDevice* pDevice,
     57                               CFX_Matrix* pUser2Device,
     58                               FX_DWORD dwFlags) {
     59   ASSERT(pPageView);
     60   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
     61 
     62   if (IsVisible(pWidget)) {
     63     if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
     64       if (pFormFiller->IsValid()) {
     65         pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
     66         pAnnot->GetPDFPage();
     67 
     68         CPDFSDK_Document* pDocument = m_pApp->GetSDKDocument();
     69         if (pDocument->GetFocusAnnot() == pAnnot) {
     70           CPDF_Rect rcFocus = pFormFiller->GetFocusBox(pPageView);
     71           if (!rcFocus.IsEmpty()) {
     72             CFX_PathData path;
     73             path.SetPointCount(5);
     74             path.SetPoint(0, rcFocus.left, rcFocus.top, FXPT_MOVETO);
     75             path.SetPoint(1, rcFocus.left, rcFocus.bottom, FXPT_LINETO);
     76             path.SetPoint(2, rcFocus.right, rcFocus.bottom, FXPT_LINETO);
     77             path.SetPoint(3, rcFocus.right, rcFocus.top, FXPT_LINETO);
     78             path.SetPoint(4, rcFocus.left, rcFocus.top, FXPT_LINETO);
     79 
     80             CFX_GraphStateData gsd;
     81             gsd.SetDashCount(1);
     82             gsd.m_DashArray[0] = 1.0f;
     83             gsd.m_DashPhase = 0;
     84             gsd.m_LineWidth = 1.0f;
     85             pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
     86                               ArgbEncode(255, 0, 0, 0), FXFILL_ALTERNATE);
     87           }
     88         }
     89         return;
     90       }
     91     }
     92 
     93     if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
     94       pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, pUser2Device,
     95                                   dwFlags);
     96     else
     97       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
     98 
     99     if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget))
    100       pWidget->DrawShadow(pDevice, pPageView);
    101   }
    102 }
    103 
    104 void CFFL_IFormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {
    105   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    106     pFormFiller->OnCreate(pAnnot);
    107   }
    108 }
    109 
    110 void CFFL_IFormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {
    111   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    112     pFormFiller->OnLoad(pAnnot);
    113   }
    114 }
    115 
    116 void CFFL_IFormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {
    117   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    118     pFormFiller->OnDelete(pAnnot);
    119   }
    120 
    121   UnRegisterFormFiller(pAnnot);
    122 }
    123 
    124 void CFFL_IFormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
    125                                     CPDFSDK_Annot* pAnnot,
    126                                     FX_UINT nFlag) {
    127   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    128 
    129   if (!m_bNotifying) {
    130     CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
    131     if (pWidget->GetAAction(CPDF_AAction::CursorEnter)) {
    132       m_bNotifying = TRUE;
    133 
    134       int nValueAge = pWidget->GetValueAge();
    135 
    136       pWidget->ClearAppModified();
    137 
    138       ASSERT(pPageView);
    139 
    140       PDFSDK_FieldAction fa;
    141       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    142       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    143       pWidget->OnAAction(CPDF_AAction::CursorEnter, fa, pPageView);
    144       m_bNotifying = FALSE;
    145 
    146       if (pWidget->IsAppModified()) {
    147         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    148           pFormFiller->ResetPDFWindow(pPageView,
    149                                       pWidget->GetValueAge() == nValueAge);
    150         }
    151       }
    152     }
    153   }
    154 
    155   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE)) {
    156     pFormFiller->OnMouseEnter(pPageView, pAnnot);
    157   }
    158 }
    159 
    160 void CFFL_IFormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
    161                                    CPDFSDK_Annot* pAnnot,
    162                                    FX_UINT nFlag) {
    163   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    164 
    165   if (!m_bNotifying) {
    166     CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
    167     if (pWidget->GetAAction(CPDF_AAction::CursorExit)) {
    168       m_bNotifying = TRUE;
    169       pWidget->GetAppearanceAge();
    170       int nValueAge = pWidget->GetValueAge();
    171       pWidget->ClearAppModified();
    172 
    173       ASSERT(pPageView);
    174 
    175       PDFSDK_FieldAction fa;
    176       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    177       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    178 
    179       pWidget->OnAAction(CPDF_AAction::CursorExit, fa, pPageView);
    180       m_bNotifying = FALSE;
    181 
    182       if (pWidget->IsAppModified()) {
    183         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    184           pFormFiller->ResetPDFWindow(pPageView,
    185                                       nValueAge == pWidget->GetValueAge());
    186         }
    187       }
    188     }
    189   }
    190 
    191   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    192     pFormFiller->OnMouseExit(pPageView, pAnnot);
    193   }
    194 }
    195 
    196 FX_BOOL CFFL_IFormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
    197                                         CPDFSDK_Annot* pAnnot,
    198                                         FX_UINT nFlags,
    199                                         const CPDF_Point& point) {
    200   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    201 
    202   if (!m_bNotifying) {
    203     CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
    204     if (Annot_HitTest(pPageView, pAnnot, point) &&
    205         pWidget->GetAAction(CPDF_AAction::ButtonDown)) {
    206       m_bNotifying = TRUE;
    207       pWidget->GetAppearanceAge();
    208       int nValueAge = pWidget->GetValueAge();
    209       pWidget->ClearAppModified();
    210 
    211       ASSERT(pPageView);
    212 
    213       PDFSDK_FieldAction fa;
    214       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlags);
    215       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlags);
    216       pWidget->OnAAction(CPDF_AAction::ButtonDown, fa, pPageView);
    217       m_bNotifying = FALSE;
    218 
    219       if (!IsValidAnnot(pPageView, pAnnot))
    220         return TRUE;
    221 
    222       if (pWidget->IsAppModified()) {
    223         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    224           pFormFiller->ResetPDFWindow(pPageView,
    225                                       nValueAge == pWidget->GetValueAge());
    226         }
    227       }
    228     }
    229   }
    230 
    231   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    232     return pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
    233   }
    234 
    235   return FALSE;
    236 }
    237 
    238 FX_BOOL CFFL_IFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
    239                                       CPDFSDK_Annot* pAnnot,
    240                                       FX_UINT nFlags,
    241                                       const CPDF_Point& point) {
    242   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    243   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
    244   CPDFSDK_Document* pDocument = m_pApp->GetSDKDocument();
    245 
    246   switch (pWidget->GetFieldType()) {
    247     case FIELDTYPE_PUSHBUTTON:
    248     case FIELDTYPE_CHECKBOX:
    249     case FIELDTYPE_RADIOBUTTON:
    250       if (GetViewBBox(pPageView, pAnnot).Contains((int)point.x, (int)point.y))
    251         pDocument->SetFocusAnnot(pAnnot);
    252       break;
    253     default:
    254       pDocument->SetFocusAnnot(pAnnot);
    255       break;
    256   }
    257 
    258   FX_BOOL bRet = FALSE;
    259 
    260   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    261     bRet = pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
    262   }
    263 
    264   if (pDocument->GetFocusAnnot() == pAnnot) {
    265     FX_BOOL bExit = FALSE;
    266     FX_BOOL bReset = FALSE;
    267     OnButtonUp(pWidget, pPageView, bReset, bExit, nFlags);
    268     if (bExit)
    269       return TRUE;
    270 #ifdef PDF_ENABLE_XFA
    271     OnClick(pWidget, pPageView, bReset, bExit, nFlags);
    272     if (bExit)
    273       return TRUE;
    274 #endif  // PDF_ENABLE_XFA
    275   }
    276   return bRet;
    277 }
    278 
    279 void CFFL_IFormFiller::OnButtonUp(CPDFSDK_Widget* pWidget,
    280                                   CPDFSDK_PageView* pPageView,
    281                                   FX_BOOL& bReset,
    282                                   FX_BOOL& bExit,
    283                                   FX_UINT nFlag) {
    284   ASSERT(pWidget);
    285 
    286   if (!m_bNotifying) {
    287     if (pWidget->GetAAction(CPDF_AAction::ButtonUp)) {
    288       m_bNotifying = TRUE;
    289       int nAge = pWidget->GetAppearanceAge();
    290       int nValueAge = pWidget->GetValueAge();
    291 
    292       ASSERT(pPageView);
    293 
    294       PDFSDK_FieldAction fa;
    295       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    296       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    297 
    298       pWidget->OnAAction(CPDF_AAction::ButtonUp, fa, pPageView);
    299       m_bNotifying = FALSE;
    300 
    301       if (!IsValidAnnot(pPageView, pWidget)) {
    302         bExit = TRUE;
    303         return;
    304       }
    305 
    306       if (nAge != pWidget->GetAppearanceAge()) {
    307         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    308           pFormFiller->ResetPDFWindow(pPageView,
    309                                       nValueAge == pWidget->GetValueAge());
    310         }
    311 
    312         bReset = TRUE;
    313       }
    314     }
    315   }
    316 }
    317 
    318 FX_BOOL CFFL_IFormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
    319                                           CPDFSDK_Annot* pAnnot,
    320                                           FX_UINT nFlags,
    321                                           const CPDF_Point& point) {
    322   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    323 
    324   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    325     return pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
    326   }
    327 
    328   return FALSE;
    329 }
    330 
    331 FX_BOOL CFFL_IFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
    332                                       CPDFSDK_Annot* pAnnot,
    333                                       FX_UINT nFlags,
    334                                       const CPDF_Point& point) {
    335   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    336 
    337   // change cursor
    338   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE)) {
    339     return pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
    340   }
    341 
    342   return FALSE;
    343 }
    344 
    345 FX_BOOL CFFL_IFormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
    346                                        CPDFSDK_Annot* pAnnot,
    347                                        FX_UINT nFlags,
    348                                        short zDelta,
    349                                        const CPDF_Point& point) {
    350   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    351 
    352   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    353     return pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
    354   }
    355 
    356   return FALSE;
    357 }
    358 
    359 FX_BOOL CFFL_IFormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
    360                                         CPDFSDK_Annot* pAnnot,
    361                                         FX_UINT nFlags,
    362                                         const CPDF_Point& point) {
    363   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    364 
    365   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    366     return pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
    367   }
    368 
    369   return FALSE;
    370 }
    371 
    372 FX_BOOL CFFL_IFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
    373                                       CPDFSDK_Annot* pAnnot,
    374                                       FX_UINT nFlags,
    375                                       const CPDF_Point& point) {
    376   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    377 
    378   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    379     return pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
    380   }
    381 
    382   return FALSE;
    383 }
    384 
    385 FX_BOOL CFFL_IFormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
    386                                     FX_UINT nKeyCode,
    387                                     FX_UINT nFlags) {
    388   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    389 
    390   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    391     return pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlags);
    392   }
    393 
    394   return FALSE;
    395 }
    396 
    397 FX_BOOL CFFL_IFormFiller::OnChar(CPDFSDK_Annot* pAnnot,
    398                                  FX_UINT nChar,
    399                                  FX_UINT nFlags) {
    400   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    401   if (nChar == FWL_VKEY_Tab)
    402     return TRUE;
    403 
    404   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
    405     return pFormFiller->OnChar(pAnnot, nChar, nFlags);
    406 
    407   return FALSE;
    408 }
    409 
    410 FX_BOOL CFFL_IFormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
    411   if (!pAnnot)
    412     return FALSE;
    413 
    414   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    415 
    416   if (!m_bNotifying) {
    417     CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
    418     if (pWidget->GetAAction(CPDF_AAction::GetFocus)) {
    419       m_bNotifying = TRUE;
    420       pWidget->GetAppearanceAge();
    421 
    422       int nValueAge = pWidget->GetValueAge();
    423       pWidget->ClearAppModified();
    424 
    425       CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
    426       ASSERT(pPageView);
    427 
    428       PDFSDK_FieldAction fa;
    429       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    430       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    431 
    432       CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, TRUE);
    433       if (!pFormFiller)
    434         return FALSE;
    435       pFormFiller->GetActionData(pPageView, CPDF_AAction::GetFocus, fa);
    436       pWidget->OnAAction(CPDF_AAction::GetFocus, fa, pPageView);
    437       m_bNotifying = FALSE;
    438 
    439       if (pWidget->IsAppModified()) {
    440         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    441           pFormFiller->ResetPDFWindow(pPageView,
    442                                       nValueAge == pWidget->GetValueAge());
    443         }
    444       }
    445     }
    446   }
    447 
    448   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
    449     pFormFiller->SetFocusForAnnot(pAnnot, nFlag);
    450 
    451   return TRUE;
    452 }
    453 
    454 FX_BOOL CFFL_IFormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
    455   if (!pAnnot)
    456     return FALSE;
    457   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
    458 
    459   if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
    460     pFormFiller->KillFocusForAnnot(pAnnot, nFlag);
    461 
    462     if (!m_bNotifying) {
    463       CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
    464       if (pWidget->GetAAction(CPDF_AAction::LoseFocus)) {
    465         m_bNotifying = TRUE;
    466         pWidget->ClearAppModified();
    467 
    468         CPDFSDK_PageView* pPageView = pWidget->GetPageView();
    469         ASSERT(pPageView);
    470 
    471         PDFSDK_FieldAction fa;
    472         fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    473         fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    474 
    475         pFormFiller->GetActionData(pPageView, CPDF_AAction::LoseFocus, fa);
    476 
    477         pWidget->OnAAction(CPDF_AAction::LoseFocus, fa, pPageView);
    478         m_bNotifying = FALSE;
    479       }
    480     }
    481   }
    482 
    483   return TRUE;
    484 }
    485 
    486 FX_BOOL CFFL_IFormFiller::IsVisible(CPDFSDK_Widget* pWidget) {
    487   return pWidget->IsVisible();
    488 }
    489 
    490 FX_BOOL CFFL_IFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget) {
    491   int nFieldFlags = pWidget->GetFieldFlags();
    492   return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
    493 }
    494 
    495 FX_BOOL CFFL_IFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget) {
    496   if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
    497     return TRUE;
    498 
    499   CPDF_Page* pPage = pWidget->GetPDFPage();
    500   CPDF_Document* pDocument = pPage->m_pDocument;
    501   FX_DWORD dwPermissions = pDocument->GetUserPermissions();
    502   return (dwPermissions & FPDFPERM_FILL_FORM) ||
    503          (dwPermissions & FPDFPERM_ANNOT_FORM) ||
    504          (dwPermissions & FPDFPERM_MODIFY);
    505 }
    506 
    507 CFFL_FormFiller* CFFL_IFormFiller::GetFormFiller(CPDFSDK_Annot* pAnnot,
    508                                                  FX_BOOL bRegister) {
    509   auto it = m_Maps.find(pAnnot);
    510   if (it != m_Maps.end())
    511     return it->second;
    512 
    513   if (!bRegister)
    514     return nullptr;
    515 
    516   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
    517   int nFieldType = pWidget->GetFieldType();
    518   CFFL_FormFiller* pFormFiller;
    519   switch (nFieldType) {
    520     case FIELDTYPE_PUSHBUTTON:
    521       pFormFiller = new CFFL_PushButton(m_pApp, pWidget);
    522       break;
    523     case FIELDTYPE_CHECKBOX:
    524       pFormFiller = new CFFL_CheckBox(m_pApp, pWidget);
    525       break;
    526     case FIELDTYPE_RADIOBUTTON:
    527       pFormFiller = new CFFL_RadioButton(m_pApp, pWidget);
    528       break;
    529     case FIELDTYPE_TEXTFIELD:
    530       pFormFiller = new CFFL_TextField(m_pApp, pWidget);
    531       break;
    532     case FIELDTYPE_LISTBOX:
    533       pFormFiller = new CFFL_ListBox(m_pApp, pWidget);
    534       break;
    535     case FIELDTYPE_COMBOBOX:
    536       pFormFiller = new CFFL_ComboBox(m_pApp, pWidget);
    537       break;
    538     case FIELDTYPE_UNKNOWN:
    539     default:
    540       pFormFiller = nullptr;
    541       break;
    542   }
    543 
    544   if (!pFormFiller)
    545     return nullptr;
    546 
    547   m_Maps[pAnnot] = pFormFiller;
    548   return pFormFiller;
    549 }
    550 
    551 void CFFL_IFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot) {
    552   if (pAnnot) {
    553     UnRegisterFormFiller(pAnnot);
    554   }
    555 }
    556 
    557 void CFFL_IFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot) {
    558   auto it = m_Maps.find(pAnnot);
    559   if (it == m_Maps.end())
    560     return;
    561 
    562   delete it->second;
    563   m_Maps.erase(it);
    564 }
    565 
    566 void CFFL_IFormFiller::QueryWherePopup(void* pPrivateData,
    567                                        FX_FLOAT fPopupMin,
    568                                        FX_FLOAT fPopupMax,
    569                                        int32_t& nRet,
    570                                        FX_FLOAT& fPopupRet) {
    571   CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
    572 
    573   CPDF_Rect rcPageView(0, 0, 0, 0);
    574   rcPageView.right = pData->pWidget->GetPDFPage()->GetPageWidth();
    575   rcPageView.bottom = pData->pWidget->GetPDFPage()->GetPageHeight();
    576   rcPageView.Normalize();
    577 
    578   CPDF_Rect rcAnnot = pData->pWidget->GetRect();
    579 
    580   FX_FLOAT fTop = 0.0f;
    581   FX_FLOAT fBottom = 0.0f;
    582 
    583   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pData->pWidget;
    584   switch (pWidget->GetRotate() / 90) {
    585     default:
    586     case 0:
    587       fTop = rcPageView.top - rcAnnot.top;
    588       fBottom = rcAnnot.bottom - rcPageView.bottom;
    589       break;
    590     case 1:
    591       fTop = rcAnnot.left - rcPageView.left;
    592       fBottom = rcPageView.right - rcAnnot.right;
    593       break;
    594     case 2:
    595       fTop = rcAnnot.bottom - rcPageView.bottom;
    596       fBottom = rcPageView.top - rcAnnot.top;
    597       break;
    598     case 3:
    599       fTop = rcPageView.right - rcAnnot.right;
    600       fBottom = rcAnnot.left - rcPageView.left;
    601       break;
    602   }
    603 
    604   FX_FLOAT fFactHeight = 0;
    605   FX_BOOL bBottom = TRUE;
    606   FX_FLOAT fMaxListBoxHeight = 0;
    607   if (fPopupMax > FFL_MAXLISTBOXHEIGHT) {
    608     if (fPopupMin > FFL_MAXLISTBOXHEIGHT) {
    609       fMaxListBoxHeight = fPopupMin;
    610     } else {
    611       fMaxListBoxHeight = FFL_MAXLISTBOXHEIGHT;
    612     }
    613   } else {
    614     fMaxListBoxHeight = fPopupMax;
    615   }
    616 
    617   if (fBottom > fMaxListBoxHeight) {
    618     fFactHeight = fMaxListBoxHeight;
    619     bBottom = TRUE;
    620   } else {
    621     if (fTop > fMaxListBoxHeight) {
    622       fFactHeight = fMaxListBoxHeight;
    623       bBottom = FALSE;
    624     } else {
    625       if (fTop > fBottom) {
    626         fFactHeight = fTop;
    627         bBottom = FALSE;
    628       } else {
    629         fFactHeight = fBottom;
    630         bBottom = TRUE;
    631       }
    632     }
    633   }
    634 
    635   nRet = bBottom ? 0 : 1;
    636   fPopupRet = fFactHeight;
    637 }
    638 
    639 void CFFL_IFormFiller::OnKeyStrokeCommit(CPDFSDK_Widget* pWidget,
    640                                          CPDFSDK_PageView* pPageView,
    641                                          FX_BOOL& bRC,
    642                                          FX_BOOL& bExit,
    643                                          FX_DWORD nFlag) {
    644   if (!m_bNotifying) {
    645     if (pWidget->GetAAction(CPDF_AAction::KeyStroke)) {
    646       m_bNotifying = TRUE;
    647       pWidget->ClearAppModified();
    648 
    649       ASSERT(pPageView);
    650 
    651       PDFSDK_FieldAction fa;
    652       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    653       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    654       fa.bWillCommit = TRUE;
    655       fa.bKeyDown = TRUE;
    656       fa.bRC = TRUE;
    657 
    658       CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
    659       pFormFiller->GetActionData(pPageView, CPDF_AAction::KeyStroke, fa);
    660       pFormFiller->SaveState(pPageView);
    661 
    662       PDFSDK_FieldAction faOld = fa;
    663       pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pPageView);
    664 
    665       bRC = fa.bRC;
    666       m_bNotifying = FALSE;
    667     }
    668   }
    669 }
    670 
    671 void CFFL_IFormFiller::OnValidate(CPDFSDK_Widget* pWidget,
    672                                   CPDFSDK_PageView* pPageView,
    673                                   FX_BOOL& bRC,
    674                                   FX_BOOL& bExit,
    675                                   FX_DWORD nFlag) {
    676   if (!m_bNotifying) {
    677     if (pWidget->GetAAction(CPDF_AAction::Validate)) {
    678       m_bNotifying = TRUE;
    679       pWidget->ClearAppModified();
    680 
    681       ASSERT(pPageView);
    682 
    683       PDFSDK_FieldAction fa;
    684       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    685       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    686       fa.bKeyDown = TRUE;
    687       fa.bRC = TRUE;
    688 
    689       CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
    690       pFormFiller->GetActionData(pPageView, CPDF_AAction::Validate, fa);
    691       pFormFiller->SaveState(pPageView);
    692 
    693       PDFSDK_FieldAction faOld = fa;
    694       pWidget->OnAAction(CPDF_AAction::Validate, fa, pPageView);
    695 
    696       bRC = fa.bRC;
    697       m_bNotifying = FALSE;
    698     }
    699   }
    700 }
    701 
    702 void CFFL_IFormFiller::OnCalculate(CPDFSDK_Widget* pWidget,
    703                                    CPDFSDK_PageView* pPageView,
    704                                    FX_BOOL& bExit,
    705                                    FX_DWORD nFlag) {
    706   if (!m_bNotifying) {
    707     ASSERT(pWidget);
    708     CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
    709     CPDFSDK_InterForm* pInterForm =
    710         (CPDFSDK_InterForm*)pDocument->GetInterForm();
    711     pInterForm->OnCalculate(pWidget->GetFormField());
    712 
    713     m_bNotifying = FALSE;
    714   }
    715 }
    716 
    717 void CFFL_IFormFiller::OnFormat(CPDFSDK_Widget* pWidget,
    718                                 CPDFSDK_PageView* pPageView,
    719                                 FX_BOOL& bExit,
    720                                 FX_DWORD nFlag) {
    721   if (!m_bNotifying) {
    722     ASSERT(pWidget);
    723     CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
    724     CPDFSDK_InterForm* pInterForm =
    725         (CPDFSDK_InterForm*)pDocument->GetInterForm();
    726 
    727     FX_BOOL bFormated = FALSE;
    728     CFX_WideString sValue =
    729         pInterForm->OnFormat(pWidget->GetFormField(), bFormated);
    730 
    731     if (bExit)
    732       return;
    733 
    734     if (bFormated) {
    735       pInterForm->ResetFieldAppearance(pWidget->GetFormField(), sValue.c_str(),
    736                                        TRUE);
    737       pInterForm->UpdateField(pWidget->GetFormField());
    738     }
    739 
    740     m_bNotifying = FALSE;
    741   }
    742 }
    743 
    744 #ifdef PDF_ENABLE_XFA
    745 void CFFL_IFormFiller::OnClick(CPDFSDK_Widget* pWidget,
    746                                CPDFSDK_PageView* pPageView,
    747                                FX_BOOL& bReset,
    748                                FX_BOOL& bExit,
    749                                FX_UINT nFlag) {
    750   ASSERT(pWidget != NULL);
    751 
    752   if (!m_bNotifying) {
    753     if (pWidget->HasXFAAAction(PDFSDK_XFA_Click)) {
    754       m_bNotifying = TRUE;
    755       int nAge = pWidget->GetAppearanceAge();
    756       int nValueAge = pWidget->GetValueAge();
    757 
    758       PDFSDK_FieldAction fa;
    759       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    760       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    761 
    762       pWidget->OnXFAAAction(PDFSDK_XFA_Click, fa, pPageView);
    763       m_bNotifying = FALSE;
    764 
    765       if (!IsValidAnnot(pPageView, pWidget)) {
    766         bExit = TRUE;
    767         return;
    768       }
    769 
    770       if (nAge != pWidget->GetAppearanceAge()) {
    771         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    772           pFormFiller->ResetPDFWindow(pPageView,
    773                                       nValueAge == pWidget->GetValueAge());
    774         }
    775 
    776         bReset = TRUE;
    777       }
    778     }
    779   }
    780 }
    781 
    782 void CFFL_IFormFiller::OnFull(CPDFSDK_Widget* pWidget,
    783                               CPDFSDK_PageView* pPageView,
    784                               FX_BOOL& bReset,
    785                               FX_BOOL& bExit,
    786                               FX_UINT nFlag) {
    787   ASSERT(pWidget != NULL);
    788 
    789   if (!m_bNotifying) {
    790     if (pWidget->HasXFAAAction(PDFSDK_XFA_Full)) {
    791       m_bNotifying = TRUE;
    792       int nAge = pWidget->GetAppearanceAge();
    793       int nValueAge = pWidget->GetValueAge();
    794 
    795       PDFSDK_FieldAction fa;
    796       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    797       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    798 
    799       pWidget->OnXFAAAction(PDFSDK_XFA_Full, fa, pPageView);
    800       m_bNotifying = FALSE;
    801 
    802       if (!IsValidAnnot(pPageView, pWidget)) {
    803         bExit = TRUE;
    804         return;
    805       }
    806 
    807       if (nAge != pWidget->GetAppearanceAge()) {
    808         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    809           pFormFiller->ResetPDFWindow(pPageView,
    810                                       nValueAge == pWidget->GetValueAge());
    811         }
    812 
    813         bReset = TRUE;
    814       }
    815     }
    816   }
    817 }
    818 
    819 void CFFL_IFormFiller::OnPopupPreOpen(void* pPrivateData,
    820                                       FX_BOOL& bExit,
    821                                       FX_DWORD nFlag) {
    822   ASSERT(pPrivateData != NULL);
    823   CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
    824   ASSERT(pData->pWidget != NULL);
    825 
    826   FX_BOOL bTempReset = FALSE;
    827   FX_BOOL bTempExit = FALSE;
    828   this->OnPreOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit,
    829                   nFlag);
    830 
    831   if (bTempReset || bTempExit) {
    832     bExit = TRUE;
    833   }
    834 }
    835 
    836 void CFFL_IFormFiller::OnPopupPostOpen(void* pPrivateData,
    837                                        FX_BOOL& bExit,
    838                                        FX_DWORD nFlag) {
    839   ASSERT(pPrivateData != NULL);
    840   CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
    841   ASSERT(pData->pWidget != NULL);
    842 
    843   FX_BOOL bTempReset = FALSE;
    844   FX_BOOL bTempExit = FALSE;
    845   this->OnPostOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit,
    846                    nFlag);
    847 
    848   if (bTempReset || bTempExit) {
    849     bExit = TRUE;
    850   }
    851 }
    852 
    853 void CFFL_IFormFiller::OnPreOpen(CPDFSDK_Widget* pWidget,
    854                                  CPDFSDK_PageView* pPageView,
    855                                  FX_BOOL& bReset,
    856                                  FX_BOOL& bExit,
    857                                  FX_UINT nFlag) {
    858   ASSERT(pWidget != NULL);
    859 
    860   if (!m_bNotifying) {
    861     if (pWidget->HasXFAAAction(PDFSDK_XFA_PreOpen)) {
    862       m_bNotifying = TRUE;
    863       int nAge = pWidget->GetAppearanceAge();
    864       int nValueAge = pWidget->GetValueAge();
    865 
    866       PDFSDK_FieldAction fa;
    867       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    868       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    869 
    870       pWidget->OnXFAAAction(PDFSDK_XFA_PreOpen, fa, pPageView);
    871       m_bNotifying = FALSE;
    872 
    873       if (!IsValidAnnot(pPageView, pWidget)) {
    874         bExit = TRUE;
    875         return;
    876       }
    877 
    878       if (nAge != pWidget->GetAppearanceAge()) {
    879         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    880           pFormFiller->ResetPDFWindow(pPageView,
    881                                       nValueAge == pWidget->GetValueAge());
    882         }
    883 
    884         bReset = TRUE;
    885       }
    886     }
    887   }
    888 }
    889 
    890 void CFFL_IFormFiller::OnPostOpen(CPDFSDK_Widget* pWidget,
    891                                   CPDFSDK_PageView* pPageView,
    892                                   FX_BOOL& bReset,
    893                                   FX_BOOL& bExit,
    894                                   FX_UINT nFlag) {
    895   ASSERT(pWidget != NULL);
    896 
    897   if (!m_bNotifying) {
    898     if (pWidget->HasXFAAAction(PDFSDK_XFA_PostOpen)) {
    899       m_bNotifying = TRUE;
    900       int nAge = pWidget->GetAppearanceAge();
    901       int nValueAge = pWidget->GetValueAge();
    902 
    903       PDFSDK_FieldAction fa;
    904       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    905       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    906 
    907       pWidget->OnXFAAAction(PDFSDK_XFA_PostOpen, fa, pPageView);
    908       m_bNotifying = FALSE;
    909 
    910       if (!IsValidAnnot(pPageView, pWidget)) {
    911         bExit = TRUE;
    912         return;
    913       }
    914 
    915       if (nAge != pWidget->GetAppearanceAge()) {
    916         if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
    917           pFormFiller->ResetPDFWindow(pPageView,
    918                                       nValueAge == pWidget->GetValueAge());
    919         }
    920 
    921         bReset = TRUE;
    922       }
    923     }
    924   }
    925 }
    926 #endif  // PDF_ENABLE_XFA
    927 
    928 FX_BOOL CFFL_IFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView,
    929                                        CPDFSDK_Annot* pAnnot) {
    930   if (pPageView)
    931     return pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
    932 
    933   return FALSE;
    934 }
    935 
    936 void CFFL_IFormFiller::OnBeforeKeyStroke(void* pPrivateData,
    937                                          CFX_WideString& strChange,
    938                                          const CFX_WideString& strChangeEx,
    939                                          int nSelStart,
    940                                          int nSelEnd,
    941                                          FX_BOOL bKeyDown,
    942                                          FX_BOOL& bRC,
    943                                          FX_BOOL& bExit,
    944                                          FX_DWORD nFlag) {
    945   CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
    946   ASSERT(pData->pWidget);
    947 
    948   CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
    949 
    950 #ifdef PDF_ENABLE_XFA
    951   if (pFormFiller->IsFieldFull(pData->pPageView)) {
    952     FX_BOOL bFullExit = FALSE;
    953     FX_BOOL bFullReset = FALSE;
    954     OnFull(pData->pWidget, pData->pPageView, bFullReset, bFullExit, nFlag);
    955 
    956     if (bFullReset || bFullExit) {
    957       bExit = TRUE;
    958       return;
    959     }
    960   }
    961 #endif  // PDF_ENABLE_XFA
    962 
    963   if (!m_bNotifying) {
    964     if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke)) {
    965       m_bNotifying = TRUE;
    966       int nAge = pData->pWidget->GetAppearanceAge();
    967       int nValueAge = pData->pWidget->GetValueAge();
    968 
    969       CPDFSDK_Document* pDocument = pData->pPageView->GetSDKDocument();
    970 
    971       PDFSDK_FieldAction fa;
    972       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
    973       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
    974       fa.sChange = strChange;
    975       fa.sChangeEx = strChangeEx;
    976       fa.bKeyDown = bKeyDown;
    977       fa.bWillCommit = FALSE;
    978       fa.bRC = TRUE;
    979       fa.nSelStart = nSelStart;
    980       fa.nSelEnd = nSelEnd;
    981 
    982       pFormFiller->GetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
    983       pFormFiller->SaveState(pData->pPageView);
    984 
    985       if (pData->pWidget->OnAAction(CPDF_AAction::KeyStroke, fa,
    986                                     pData->pPageView)) {
    987         if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
    988           bExit = TRUE;
    989           m_bNotifying = FALSE;
    990           return;
    991         }
    992 
    993         if (nAge != pData->pWidget->GetAppearanceAge()) {
    994           CPWL_Wnd* pWnd = pFormFiller->ResetPDFWindow(
    995               pData->pPageView, nValueAge == pData->pWidget->GetValueAge());
    996           pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
    997           bExit = TRUE;
    998         }
    999 
   1000         if (fa.bRC) {
   1001           pFormFiller->SetActionData(pData->pPageView, CPDF_AAction::KeyStroke,
   1002                                      fa);
   1003           bRC = FALSE;
   1004         } else {
   1005           pFormFiller->RestoreState(pData->pPageView);
   1006           bRC = FALSE;
   1007         }
   1008 
   1009         if (pDocument->GetFocusAnnot() != pData->pWidget) {
   1010           pFormFiller->CommitData(pData->pPageView, nFlag);
   1011           bExit = TRUE;
   1012         }
   1013       } else {
   1014         if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
   1015           bExit = TRUE;
   1016           m_bNotifying = FALSE;
   1017           return;
   1018         }
   1019       }
   1020 
   1021       m_bNotifying = FALSE;
   1022     }
   1023   }
   1024 }
   1025