7#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
11#include "constants/access_permissions.h"
12#include "constants/ascii.h"
13#include "constants/form_flags.h"
14#include "core/fpdfapi/page/cpdf_page.h"
15#include "core/fxcrt/autorestorer.h"
16#include "core/fxge/cfx_drawutils.h"
17#include "fpdfsdk/cpdfsdk_pageview.h"
18#include "fpdfsdk/cpdfsdk_widget.h"
19#include "fpdfsdk/formfiller/cffl_checkbox.h"
20#include "fpdfsdk/formfiller/cffl_combobox.h"
21#include "fpdfsdk/formfiller/cffl_formfield.h"
22#include "fpdfsdk/formfiller/cffl_listbox.h"
23#include "fpdfsdk/formfiller/cffl_perwindowdata.h"
24#include "fpdfsdk/formfiller/cffl_pushbutton.h"
25#include "fpdfsdk/formfiller/cffl_radiobutton.h"
26#include "fpdfsdk/formfiller/cffl_textfield.h"
27#include "public/fpdf_fwlevent.h"
28#include "third_party/base/check.h"
36bool CFFL_InteractiveFormFiller::
Annot_HitTest(
const CPDFSDK_Widget* pWidget,
37 const CFX_PointF& point) {
38 return pWidget
->GetRect().Contains(point);
42 const CPDFSDK_PageView* pPageView,
43 CPDFSDK_Widget* pWidget) {
58void CFFL_InteractiveFormFiller::
OnDraw(CPDFSDK_PageView* pPageView,
59 CPDFSDK_Widget* pWidget,
68 pFormField
->OnDraw(pPageView
, pWidget
, pDevice
, mtUser2Device
);
69 if (m_pCallbackIface->GetFocusAnnot() != pWidget)
92void CFFL_InteractiveFormFiller::
OnDelete(CPDFSDK_Widget* pWidget) {
93 UnregisterFormField(pWidget);
97 CPDFSDK_PageView* pPageView,
98 ObservedPtr<CPDFSDK_Widget>& pWidget,
99 Mask<FWL_EVENTFLAG> nFlag) {
101 if (pWidget->GetAAction(CPDF_AAction::kCursorEnter).HasDict()) {
102 uint32_t nValueAge = pWidget->GetValueAge();
103 pWidget->ClearAppModified();
112 pWidget->OnAAction(CPDF_AAction::kCursorEnter, &fa, pPageView);
117 if (pWidget->IsAppModified()) {
125 if (
CFFL_FormField* pFormField = GetOrCreateFormField(pWidget.Get()))
130 CPDFSDK_PageView* pPageView,
131 ObservedPtr<CPDFSDK_Widget>& pWidget,
132 Mask<FWL_EVENTFLAG> nFlag) {
134 if (pWidget->GetAAction(CPDF_AAction::kCursorExit).HasDict()) {
135 uint32_t nValueAge = pWidget->GetValueAge();
136 pWidget->ClearAppModified();
145 pWidget->OnAAction(CPDF_AAction::kCursorExit, &fa, pPageView);
150 if (pWidget->IsAppModified()) {
164 CPDFSDK_PageView* pPageView,
165 ObservedPtr<CPDFSDK_Widget>& pWidget,
166 Mask<FWL_EVENTFLAG> nFlags,
167 const CFX_PointF& point) {
169 if (Annot_HitTest(pWidget.Get(), point) &&
170 pWidget->GetAAction(CPDF_AAction::kButtonDown).HasDict()) {
171 uint32_t nValueAge = pWidget->GetValueAge();
172 pWidget->ClearAppModified();
181 pWidget->OnAAction(CPDF_AAction::kButtonDown, &fa, pPageView);
189 if (pWidget->IsAppModified()) {
204 CPDFSDK_PageView* pPageView,
205 ObservedPtr<CPDFSDK_Widget>& pWidget,
206 Mask<FWL_EVENTFLAG> nFlags,
207 const CFX_PointF& point) {
209 switch (pWidget->GetFieldType()) {
210 case FormFieldType::kPushButton:
211 case FormFieldType::kCheckBox:
212 case FormFieldType::kRadioButton: {
215 bbox
.Contains(static_cast<
int>(point.x)
, static_cast<
int>(point.y)
);
224 m_pCallbackIface->SetFocusAnnot(pObserved);
228 bool bRet = pFormField &&
230 if (m_pCallbackIface->GetFocusAnnot() != pWidget.Get())
235 if (OnClick(pWidget, pPageView, nFlags) || !pWidget)
242 ObservedPtr<CPDFSDK_Widget>& pWidget,
243 const CPDFSDK_PageView* pPageView,
244 Mask<FWL_EVENTFLAG> nFlag) {
248 if (!pWidget->GetAAction(CPDF_AAction::kButtonUp).HasDict())
251 uint32_t nAge = pWidget->GetAppearanceAge();
252 uint32_t nValueAge = pWidget->GetValueAge();
261 pWidget->OnAAction(CPDF_AAction::kButtonUp, &fa, pPageView);
265 if (nAge == pWidget->GetAppearanceAge())
275 ObservedPtr<CPDFSDK_Widget>& pWidget,
283 ObservedPtr<CPDFSDK_Widget>& pWidget,
290 CPDFSDK_PageView* pPageView,
291 ObservedPtr<CPDFSDK_Widget>& pWidget,
292 Mask<FWL_EVENTFLAG> nFlags,
293 const CFX_PointF& point) {
299 CPDFSDK_PageView* pPageView,
300 ObservedPtr<CPDFSDK_Widget>& pWidget,
301 Mask<FWL_EVENTFLAG> nFlags,
302 const CFX_PointF& point) {
308 CPDFSDK_PageView* pPageView,
309 ObservedPtr<CPDFSDK_Widget>& pWidget,
310 Mask<FWL_EVENTFLAG> nFlags,
311 const CFX_PointF& point,
312 const CFX_Vector& delta) {
319 CPDFSDK_PageView* pPageView,
320 ObservedPtr<CPDFSDK_Widget>& pWidget,
321 Mask<FWL_EVENTFLAG> nFlags,
322 const CFX_PointF& point) {
328 CPDFSDK_PageView* pPageView,
329 ObservedPtr<CPDFSDK_Widget>& pWidget,
330 Mask<FWL_EVENTFLAG> nFlags,
331 const CFX_PointF& point) {
336bool CFFL_InteractiveFormFiller::
OnKeyDown(CPDFSDK_Widget* pWidget,
337 FWL_VKEYCODE nKeyCode,
338 Mask<FWL_EVENTFLAG> nFlags) {
343bool CFFL_InteractiveFormFiller::
OnChar(CPDFSDK_Widget* pWidget,
345 Mask<FWL_EVENTFLAG> nFlags) {
350 return pFormField && pFormField
->OnChar(pWidget
, nChar
, nFlags
);
354 ObservedPtr<CPDFSDK_Widget>& pWidget,
355 Mask<FWL_EVENTFLAG> nFlag) {
360 if (pWidget->GetAAction(CPDF_AAction::kGetFocus).HasDict()) {
361 uint32_t nValueAge = pWidget->GetValueAge();
362 pWidget->ClearAppModified();
368 CPDFSDK_PageView* pPageView = pWidget->GetPageView();
378 pWidget->OnAAction(CPDF_AAction::kGetFocus, &fa, pPageView);
383 if (pWidget->IsAppModified()) {
393 if (
CFFL_FormField* pFormField = GetOrCreateFormField(pWidget.Get()))
400 ObservedPtr<CPDFSDK_Widget>& pWidget,
401 Mask<FWL_EVENTFLAG> nFlag) {
416 if (!pWidget->GetAAction(CPDF_AAction::kLoseFocus).HasDict())
419 pWidget->ClearAppModified();
421 CPDFSDK_PageView* pPageView = pWidget->GetPageView();
431 pWidget->OnAAction(CPDF_AAction::kLoseFocus, &fa, pPageView);
437 m_pCallbackIface->OnSetFieldInputFocus(text);
442 m_pCallbackIface->Invalidate(pPage, rect);
447 return m_pCallbackIface->GetOrCreatePageView(pPage);
451 return m_pCallbackIface->GetPageView(pPage);
455 return m_pCallbackIface->GetTimerHandler();
459 m_pCallbackIface->OnChange();
462bool CFFL_InteractiveFormFiller::
IsVisible(CPDFSDK_Widget* pWidget) {
466bool CFFL_InteractiveFormFiller::
IsReadOnly(CPDFSDK_Widget* pWidget) {
471bool CFFL_InteractiveFormFiller::IsFillingAllowed(
472 CPDFSDK_Widget* pWidget)
const {
476 return m_pCallbackIface->HasPermissions(
477 pdfium::access_permissions::kFillForm |
478 pdfium::access_permissions::kModifyAnnotation |
479 pdfium::access_permissions::kModifyContent);
483 CPDFSDK_Widget* pWidget) {
484 auto it = m_Map.find(pWidget);
485 return it != m_Map.end() ? it->second.get() :
nullptr;
489 CPDFSDK_Widget* pWidget) {
494 std::unique_ptr<CFFL_FormField> pFormField;
497 pFormField =
std::make_unique<CFFL_PushButton>(
this, pWidget);
500 pFormField =
std::make_unique<CFFL_CheckBox>(
this, pWidget);
503 pFormField =
std::make_unique<CFFL_RadioButton>(
this, pWidget);
506 pFormField =
std::make_unique<CFFL_TextField>(
this, pWidget);
509 pFormField =
std::make_unique<CFFL_ListBox>(
this, pWidget);
512 pFormField =
std::make_unique<CFFL_ComboBox>(
this, pWidget);
519 result = pFormField.get();
520 m_Map[pWidget] = std::move(pFormField);
524WideString CFFL_InteractiveFormFiller::
GetText(CPDFSDK_Widget* pWidget) {
530 CPDFSDK_Widget* pWidget) {
536 CPDFSDK_Widget* pWidget,
537 const WideString& text) {
546 const WideString& text) {
559bool CFFL_InteractiveFormFiller::
CanUndo(CPDFSDK_Widget* pWidget) {
564bool CFFL_InteractiveFormFiller::
CanRedo(CPDFSDK_Widget* pWidget) {
569bool CFFL_InteractiveFormFiller::
Undo(CPDFSDK_Widget* pWidget) {
571 return pFormField && pFormField
->Undo();
574bool CFFL_InteractiveFormFiller::
Redo(CPDFSDK_Widget* pWidget) {
576 return pFormField && pFormField
->Redo();
579void CFFL_InteractiveFormFiller::UnregisterFormField(CPDFSDK_Widget* pWidget) {
580 auto it = m_Map.find(pWidget);
581 if (it == m_Map.end())
589 auto* pPrivateData =
static_cast<CFFL_PerWindowData*>(pWidgetData);
594 m_pCallbackIface->InvalidateRect(pWidget, rect);
599 auto* pPrivateData =
static_cast<CFFL_PerWindowData*>(pWidgetData);
607 m_pCallbackIface->OutputSelectedRect(pFormField, rect);
611 return m_pCallbackIface->IsSelectionImplemented();
615 m_pCallbackIface->SetCursor(nCursorStyle);
624 auto* pData =
static_cast<
const CFFL_PerWindowData*>(pAttached);
633 float fBottom = 0.0f;
637 fTop = rcPageView
.top - rcAnnot
.top;
646 fBottom = rcPageView
.top - rcAnnot
.top;
654 constexpr float kMaxListBoxHeight = 140;
655 const float fMaxListBoxHeight =
656 std::clamp(kMaxListBoxHeight, fPopupMin, fPopupMax);
658 if (fBottom > fMaxListBoxHeight) {
659 *fPopupRet = fMaxListBoxHeight;
664 if (fTop > fMaxListBoxHeight) {
665 *fPopupRet = fMaxListBoxHeight;
670 if (fTop > fBottom) {
674 *fPopupRet = fBottom;
680 ObservedPtr<CPDFSDK_Widget>& pWidget,
681 const CPDFSDK_PageView* pPageView,
682 Mask<FWL_EVENTFLAG> nFlag) {
686 if (!pWidget->GetAAction(CPDF_AAction::kKeyStroke).HasDict())
690 pWidget->ClearAppModified();
705 pWidget->OnAAction(CPDF_AAction::kKeyStroke, &fa, pPageView);
714 ObservedPtr<CPDFSDK_Widget>& pWidget,
715 const CPDFSDK_PageView* pPageView,
716 Mask<FWL_EVENTFLAG> nFlag) {
720 if (!pWidget->GetAAction(CPDF_AAction::kValidate).HasDict())
724 pWidget->ClearAppModified();
738 pWidget->OnAAction(CPDF_AAction::kValidate, &fa, pPageView);
747 ObservedPtr<CPDFSDK_Widget>& pWidget) {
752 m_pCallbackIface->OnCalculate(pObserved);
756 ObservedPtr<CPDFSDK_Widget>& pWidget) {
761 m_pCallbackIface->OnFormat(pObserved);
765bool CFFL_InteractiveFormFiller::OnClick(ObservedPtr<CPDFSDK_Widget>& pWidget,
766 const CPDFSDK_PageView* pPageView,
767 Mask<FWL_EVENTFLAG> nFlag) {
771 if (!pWidget->HasXFAAAction(PDFSDK_XFA_Click))
774 uint32_t nAge = pWidget->GetAppearanceAge();
775 uint32_t nValueAge = pWidget->GetValueAge();
777 AutoRestorer<
bool> restorer(&m_bNotifying);
781 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
782 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
784 pWidget->OnXFAAAction(PDFSDK_XFA_Click, &fa, pPageView);
786 if (!pWidget || !IsValidAnnot(pPageView, pWidget.Get()))
788 if (nAge == pWidget->GetAppearanceAge())
791 CFFL_FormField* pFormField = GetFormField(pWidget.Get());
793 pFormField->ResetPWLWindowForValueAge(pPageView, pWidget.Get(), nValueAge);
797bool CFFL_InteractiveFormFiller::OnFull(ObservedPtr<CPDFSDK_Widget>& pWidget,
798 const CPDFSDK_PageView* pPageView,
799 Mask<FWL_EVENTFLAG> nFlag) {
803 if (!pWidget->HasXFAAAction(PDFSDK_XFA_Full))
806 uint32_t nAge = pWidget->GetAppearanceAge();
807 uint32_t nValueAge = pWidget->GetValueAge();
809 AutoRestorer<
bool> restorer(&m_bNotifying);
813 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
814 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
815 pWidget->OnXFAAAction(PDFSDK_XFA_Full, &fa, pPageView);
817 if (!pWidget || !IsValidAnnot(pPageView, pWidget.Get()))
819 if (nAge == pWidget->GetAppearanceAge())
822 CFFL_FormField* pFormField = GetFormField(pWidget.Get());
824 pFormField->ResetPWLWindowForValueAge(pPageView, pWidget.Get(), nValueAge);
828bool CFFL_InteractiveFormFiller::OnPreOpen(ObservedPtr<CPDFSDK_Widget>& pWidget,
829 const CPDFSDK_PageView* pPageView,
830 Mask<FWL_EVENTFLAG> nFlag) {
834 if (!pWidget->HasXFAAAction(PDFSDK_XFA_PreOpen))
837 uint32_t nAge = pWidget->GetAppearanceAge();
838 uint32_t nValueAge = pWidget->GetValueAge();
840 AutoRestorer<
bool> restorer(&m_bNotifying);
844 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
845 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
846 pWidget->OnXFAAAction(PDFSDK_XFA_PreOpen, &fa, pPageView);
848 if (!pWidget || !IsValidAnnot(pPageView, pWidget.Get()))
850 if (nAge == pWidget->GetAppearanceAge())
853 CFFL_FormField* pFormField = GetFormField(pWidget.Get());
855 pFormField->ResetPWLWindowForValueAge(pPageView, pWidget.Get(), nValueAge);
859bool CFFL_InteractiveFormFiller::OnPostOpen(
860 ObservedPtr<CPDFSDK_Widget>& pWidget,
861 const CPDFSDK_PageView* pPageView,
862 Mask<FWL_EVENTFLAG> nFlag) {
866 if (!pWidget->HasXFAAAction(PDFSDK_XFA_PostOpen))
869 uint32_t nAge = pWidget->GetAppearanceAge();
870 uint32_t nValueAge = pWidget->GetValueAge();
872 AutoRestorer<
bool> restorer(&m_bNotifying);
876 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
877 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
878 pWidget->OnXFAAAction(PDFSDK_XFA_PostOpen, &fa, pPageView);
880 if (!pWidget || !IsValidAnnot(pPageView, pWidget.Get()))
883 if (nAge == pWidget->GetAppearanceAge())
886 CFFL_FormField* pFormField = GetFormField(pWidget.Get());
888 pFormField->ResetPWLWindowForValueAge(pPageView, pWidget.Get(), nValueAge);
894bool CFFL_InteractiveFormFiller::
IsValidAnnot(
const CPDFSDK_PageView* pPageView,
895 CPDFSDK_Widget* pWidget) {
902 WideString& strChange,
903 const WideString& strChangeEx,
907 Mask<FWL_EVENTFLAG> nFlag) {
909 auto* pPrivateData =
static_cast<
const CFFL_PerWindowData*>(pAttached);
911 ObservedPtr<CPDFSDK_Widget> pWidget(pPrivateData->GetWidget());
917 if (pFormField->IsFieldFull(pPageView)) {
918 if (OnFull(pWidget, pPageView, nFlag) || !pWidget)
925 return {
true,
false};
931 uint32_t nAge = pWidget->GetAppearanceAge();
932 uint32_t nValueAge = pWidget->GetValueAge();
937 fa.sChange = strChange;
938 fa.sChangeEx = strChangeEx;
954 return {
true,
false};
957 if (nAge != pWidget->GetAppearanceAge()) {
972 if (m_pCallbackIface->GetFocusAnnot() == pWidget)
973 return {
false, bExit};
976 return {
false,
true};
981 Mask<FWL_EVENTFLAG> nFlag) {
983 auto* pData =
static_cast<
const CFFL_PerWindowData*>(pAttached);
984 DCHECK(pData->GetWidget());
986 ObservedPtr<CPDFSDK_Widget> pObserved(pData->GetWidget());
987 return OnPreOpen(pObserved, pData->GetPageView(), nFlag) || !pObserved;
995 Mask<FWL_EVENTFLAG> nFlag) {
997 auto* pData =
static_cast<
const CFFL_PerWindowData*>(pAttached);
998 DCHECK(pData->GetWidget());
1000 ObservedPtr<CPDFSDK_Widget> pObserved(pData->GetWidget());
1001 return OnPostOpen(pObserved, pData->GetPageView(), nFlag) || !pObserved;
CFFL_FormField * GetFormField()
const CPDFSDK_PageView * GetPageView() const
CPDFSDK_Widget * GetWidget() const
static void DrawFocusRect(CFX_RenderDevice *render_device, const CFX_Matrix &user_to_device, const CFX_FloatRect &view_bounding_box)
constexpr CFX_FloatRect(float l, float b, float r, float t)
void Inflate(float x, float y)
FX_RECT GetOuterRect() const
CPDF_Annot * GetPDFAnnot() const override
CFX_FloatRect GetRect() const override
bool IsValidAnnot(const CPDF_Annot *p) const
CFX_FloatRect GetRect() const
float GetPageHeight() const override
float GetPageWidth() const override
static bool IsCTRLKeyDown(Mask< FWL_EVENTFLAG > nFlag)
static bool IsSHIFTKeyDown(Mask< FWL_EVENTFLAG > nFlag)
bool Contains(int x, int y) const