7#include "fpdfsdk/cpdfsdk_widget.h"
9#include "constants/access_permissions.h"
10#include "constants/annotation_common.h"
11#include "constants/appearance.h"
12#include "constants/form_flags.h"
13#include "core/fpdfapi/parser/cpdf_array.h"
14#include "core/fpdfapi/parser/cpdf_dictionary.h"
15#include "core/fpdfapi/parser/cpdf_document.h"
16#include "core/fpdfapi/parser/cpdf_reference.h"
17#include "core/fpdfapi/parser/cpdf_stream.h"
18#include "core/fpdfapi/parser/cpdf_string.h"
19#include "core/fpdfdoc/cpdf_bafontmap.h"
20#include "core/fpdfdoc/cpdf_defaultappearance.h"
21#include "core/fpdfdoc/cpdf_formcontrol.h"
22#include "core/fpdfdoc/cpdf_formfield.h"
23#include "core/fpdfdoc/cpdf_iconfit.h"
24#include "core/fpdfdoc/cpdf_interactiveform.h"
25#include "core/fxge/cfx_fillrenderoptions.h"
26#include "core/fxge/cfx_graphstatedata.h"
27#include "core/fxge/cfx_path.h"
28#include "core/fxge/cfx_renderdevice.h"
29#include "fpdfsdk/cpdfsdk_appstream.h"
30#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
31#include "fpdfsdk/cpdfsdk_interactiveform.h"
32#include "fpdfsdk/cpdfsdk_pageview.h"
33#include "fpdfsdk/formfiller/cffl_fieldaction.h"
34#include "fpdfsdk/pwl/cpwl_edit.h"
35#include "third_party/base/check.h"
36#include "third_party/base/notreached.h"
39#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
40#include "xfa/fxfa/cxfa_eventparam.h"
41#include "xfa/fxfa/cxfa_ffdocview.h"
42#include "xfa/fxfa/cxfa_ffwidget.h"
43#include "xfa/fxfa/cxfa_ffwidgethandler.h"
44#include "xfa/fxfa/parser/cxfa_node.h"
48 CPDFSDK_PageView* pPageView,
49 CPDFSDK_InteractiveForm* pInteractiveForm)
55 m_pInteractiveForm->RemoveMap(GetFormControl());
59CXFA_FFWidget* CPDFSDK_Widget::GetMixXFAWidget()
const {
60 CPDF_Document::Extension* pContext =
61 GetPageView()->GetFormFillEnv()->GetDocExtension();
62 if (!pContext || !pContext->ContainsExtensionForegroundForm())
65 CXFA_FFDocView* pDocView =
66 static_cast<CPDFXFA_Context*>(pContext)->GetXFADocView();
71 if (GetFieldType() == FormFieldType::kRadioButton) {
72 sName = GetAnnotName();
82 return pDocView->GetWidgetByName(sName,
nullptr);
85CXFA_FFWidget* CPDFSDK_Widget::GetGroupMixXFAWidget()
const {
86 CPDF_Document::Extension* pContext =
87 GetPageView()->GetFormFillEnv()->GetDocExtension();
88 if (!pContext || !pContext->ContainsExtensionForegroundForm())
91 CXFA_FFDocView* pDocView =
92 static_cast<CPDFXFA_Context*>(pContext)->GetXFADocView();
96 WideString sName = GetName();
97 return !sName.IsEmpty() ? pDocView->GetWidgetByName(sName,
nullptr) :
nullptr;
100CXFA_FFWidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler()
const {
101 CPDF_Document::Extension* pContext =
102 GetPageView()->GetFormFillEnv()->GetDocExtension();
103 if (!pContext || !pContext->ContainsExtensionForegroundForm())
106 CXFA_FFDocView* pDocView =
107 static_cast<CPDFXFA_Context*>(pContext)->GetXFADocView();
108 return pDocView ? pDocView->GetWidgetHandler() :
nullptr;
111static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) {
112 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
115 case PDFSDK_XFA_Click:
116 eEventType = XFA_EVENT_Click;
118 case PDFSDK_XFA_Full:
119 eEventType = XFA_EVENT_Full;
121 case PDFSDK_XFA_PreOpen:
122 eEventType = XFA_EVENT_PreOpen;
124 case PDFSDK_XFA_PostOpen:
125 eEventType = XFA_EVENT_PostOpen;
132static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT,
134 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
137 case CPDF_AAction::kCursorEnter:
138 eEventType = XFA_EVENT_MouseEnter;
140 case CPDF_AAction::kCursorExit:
141 eEventType = XFA_EVENT_MouseExit;
143 case CPDF_AAction::kButtonDown:
144 eEventType = XFA_EVENT_MouseDown;
146 case CPDF_AAction::kButtonUp:
147 eEventType = XFA_EVENT_MouseUp;
149 case CPDF_AAction::kGetFocus:
150 eEventType = XFA_EVENT_Enter;
152 case CPDF_AAction::kLoseFocus:
153 eEventType = XFA_EVENT_Exit;
155 case CPDF_AAction::kPageOpen:
156 case CPDF_AAction::kPageClose:
157 case CPDF_AAction::kPageVisible:
158 case CPDF_AAction::kPageInvisible:
160 case CPDF_AAction::kKeyStroke:
162 eEventType = XFA_EVENT_Change;
164 case CPDF_AAction::kValidate:
165 eEventType = XFA_EVENT_Validate;
167 case CPDF_AAction::kOpenPage:
168 case CPDF_AAction::kClosePage:
169 case CPDF_AAction::kFormat:
170 case CPDF_AAction::kCalculate:
171 case CPDF_AAction::kCloseDocument:
172 case CPDF_AAction::kSaveDocument:
173 case CPDF_AAction::kDocumentSaved:
174 case CPDF_AAction::kPrintDocument:
175 case CPDF_AAction::kDocumentPrinted:
177 case CPDF_AAction::kDocumentOpen:
178 case CPDF_AAction::kNumberOfActions:
179 NOTREACHED_NORETURN();
185bool CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT)
const {
186 CXFA_FFWidget* pWidget = GetMixXFAWidget();
190 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
191 if (!pXFAWidgetHandler)
194 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
195 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
196 GetFieldType() == FormFieldType::kRadioButton) {
197 CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget();
199 hGroupWidget->HasEventUnderHandler(eEventType, pXFAWidgetHandler)) {
204 return pWidget->HasEventUnderHandler(eEventType, pXFAWidgetHandler);
207bool CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
208 CFFL_FieldAction* data,
209 const CPDFSDK_PageView* pPageView) {
210 auto* pContext =
static_cast<CPDFXFA_Context*>(
211 GetPageView()->GetFormFillEnv()->GetDocExtension());
215 CXFA_FFWidget* pWidget = GetMixXFAWidget();
219 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
220 if (eEventType == XFA_EVENT_Unknown)
223 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
224 if (!pXFAWidgetHandler)
227 CXFA_EventParam param(eEventType);
228 param.m_wsChange = data->sChange;
229 param.m_iCommitKey = 0;
230 param.m_bShift = data->bShift;
231 param.m_iSelStart = data->nSelStart;
232 param.m_iSelEnd = data->nSelEnd;
233 param.m_wsFullText = data->sValue;
234 param.m_bKeyDown = data->bKeyDown;
235 param.m_bModifier = data->bModifier;
236 param.m_wsPrevText = data->sValue;
237 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
238 GetFieldType() == FormFieldType::kRadioButton) {
239 CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget();
241 !hGroupWidget->ProcessEventUnderHandler(¶m, pXFAWidgetHandler)) {
246 bool ret = pWidget->ProcessEventUnderHandler(¶m, pXFAWidgetHandler);
247 CXFA_FFDocView* pDocView = pContext->GetXFADocView();
249 pDocView->UpdateDocView();
254void CPDFSDK_Widget::Synchronize(
bool bSynchronizeElse) {
255 CXFA_FFWidget* hWidget = GetMixXFAWidget();
259 CXFA_Node* node = hWidget->GetNode();
260 if (!node->IsWidgetReady())
263 CPDF_FormField* pFormField = GetFormField();
264 switch (GetFieldType()) {
265 case FormFieldType::kCheckBox:
266 case FormFieldType::kRadioButton: {
267 CPDF_FormControl* pFormCtrl = GetFormControl();
268 XFA_CheckState eCheckState =
269 pFormCtrl->IsChecked() ? XFA_CheckState::kOn : XFA_CheckState::kOff;
270 node->SetCheckState(eCheckState);
273 case FormFieldType::kTextField:
274 node->SetValue(XFA_ValuePicture::kEdit, pFormField->GetValue());
276 case FormFieldType::kComboBox:
277 case FormFieldType::kListBox: {
278 node->ClearAllSelections();
279 for (
int i = 0; i < pFormField->CountSelectedItems(); ++i) {
280 int nIndex = pFormField->GetSelectedIndex(i);
282 static_cast<size_t>(nIndex) < node->CountChoiceListItems(
false)) {
283 node->SetItemState(nIndex,
true,
false,
false);
286 if (GetFieldType() == FormFieldType::kComboBox)
287 node->SetValue(XFA_ValuePicture::kEdit, pFormField->GetValue());
294 if (bSynchronizeElse) {
295 auto* context =
static_cast<CPDFXFA_Context*>(
296 GetPageView()->GetFormFillEnv()->GetDocExtension());
297 context->GetXFADocView()->ProcessValueChanged(node);
301bool CPDFSDK_Widget::HandleXFAAAction(
302 CPDF_AAction::AActionType type,
303 CFFL_FieldAction* data,
304 CPDFSDK_FormFillEnvironment* pFormFillEnv) {
306 static_cast<CPDFXFA_Context*>(pFormFillEnv->GetDocExtension());
310 CXFA_FFWidget* hWidget = GetMixXFAWidget();
314 XFA_EVENTTYPE eEventType = GetXFAEventType(type, data->bWillCommit);
315 if (eEventType == XFA_EVENT_Unknown)
318 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
319 if (!pXFAWidgetHandler)
322 CXFA_EventParam param(eEventType);
323 param.m_wsChange = data->sChange;
324 param.m_iCommitKey = 0;
325 param.m_bShift = data->bShift;
326 param.m_iSelStart = data->nSelStart;
327 param.m_iSelEnd = data->nSelEnd;
328 param.m_wsFullText = data->sValue;
329 param.m_bKeyDown = data->bKeyDown;
330 param.m_bModifier = data->bModifier;
331 param.m_wsPrevText = data->sValue;
332 bool ret = hWidget->ProcessEventUnderHandler(¶m, pXFAWidgetHandler);
333 CXFA_FFDocView* pDocView = pContext->GetXFADocView();
335 pDocView->UpdateDocView();
344 GetAnnotDict()->GetDictFor(pdfium::annotation::kAP);
349 const char* ap_entry =
"N";
354 if (!pAP->KeyExist(ap_entry))
369 return pSub->IsStream();
372 if (
const CPDF_Dictionary* pSubDict = pSub->AsDictionary()) {
391 DCHECK(rect.right - rect.left >= 1.0f);
392 DCHECK(rect.top - rect.bottom >= 1.0f);
398 CPDF_Document::Extension* pContext =
399 GetPageView()->GetFormFillEnv()->GetDocExtension();
400 if (pContext && pContext->ContainsExtensionFullForm())
425 m_pInteractiveForm->GetInteractiveForm();
435WideString CPDFSDK_Widget::GetName()
const {
436 return GetFormField()->GetFullName();
444 if (type_argb_pair.color_type == CFX_Color::Type::kTransparent)
445 return absl::nullopt;
453 if (type_argb_pair.color_type == CFX_Color::Type::kTransparent)
454 return absl::nullopt;
461 absl::optional<CFX_Color::TypeAndARGB> maybe_type_argb_pair =
464 if (!maybe_type_argb_pair.has_value())
465 return absl::nullopt;
467 if (maybe_type_argb_pair.value().color_type == CFX_Color::Type::kTransparent)
468 return absl::nullopt;
470 return ArgbToColorRef(maybe_type_argb_pair.value().argb);
477 pDa.GetFont(&fFontSize);
483 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
484 CXFA_Node* node = hWidget->GetNode();
485 if (node->IsWidgetReady()) {
486 if (nIndex < node->CountSelectedItems())
487 return node->GetSelectedItem(nIndex);
497 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
498 CXFA_Node* node = hWidget->GetNode();
499 if (node->IsWidgetReady())
500 return node->GetValue(XFA_ValuePicture::kDisplay);
539 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
540 CXFA_Node* node = hWidget->GetNode();
541 if (node->IsWidgetReady()) {
543 static_cast<size_t>(nIndex) < node->CountChoiceListItems(
false)) {
544 return node->GetItemState(nIndex);
561 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
562 CXFA_Node* node = hWidget->GetNode();
563 if (node->IsWidgetReady())
564 return node->GetCheckState() == XFA_CheckState::kOn;
587 if (!IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode::kNormal))
588 ResetXFAAppearance(CPDFSDK_Widget::kValueChanged);
593void CPDFSDK_Widget::
SetValue(
const WideString& sValue) {
620 m_bAppModified =
true;
624 m_bAppModified =
false;
628 return m_bAppModified;
632void CPDFSDK_Widget::ResetXFAAppearance(ValueChanged bValueChanged) {
633 switch (GetFieldType()) {
634 case FormFieldType::kTextField:
635 case FormFieldType::kComboBox: {
636 ResetAppearance(OnFormat(), kValueChanged);
640 ResetAppearance(absl::nullopt, kValueUnchanged);
646void CPDFSDK_Widget::ResetAppearance(absl::optional<WideString> sValue,
647 ValueChanged bValueChanged) {
651 if (bValueChanged == kValueChanged)
654 CPDFSDK_AppStream appStream(
this, GetAPDict().Get());
655 switch (GetFieldType()) {
656 case FormFieldType::kPushButton:
657 appStream.SetAsPushButton();
659 case FormFieldType::kCheckBox:
660 appStream.SetAsCheckBox();
662 case FormFieldType::kRadioButton:
663 appStream.SetAsRadioButton();
665 case FormFieldType::kComboBox:
666 appStream.SetAsComboBox(sValue);
668 case FormFieldType::kListBox:
669 appStream.SetAsListBox();
671 case FormFieldType::kTextField:
672 appStream.SetAsTextField(sValue);
678 ClearCachedAnnotAP();
684 return m_pInteractiveForm->OnFormat(pFormField);
690 m_pInteractiveForm->ResetFieldAppearance(pFormField, absl::nullopt);
705bool CPDFSDK_Widget::
DoHitTest(
const CFX_PointF& point) {
714 uint32_t perms =
GetPDFPage()->GetDocument()->GetUserPermissions(
726 auto* form_filler = GetInteractiveFormFiller();
734 ObservedPtr<CPDFSDK_Widget> observer(
this);
742 ObservedPtr<CPDFSDK_Widget> observer(
this);
747 const CFX_PointF& point) {
751 ObservedPtr<CPDFSDK_Widget> observer(
this);
757 const CFX_PointF& point) {
761 ObservedPtr<CPDFSDK_Widget> observer(
this);
767 const CFX_PointF& point) {
771 ObservedPtr<CPDFSDK_Widget> observer(
this);
777 const CFX_PointF& point) {
781 ObservedPtr<CPDFSDK_Widget> observer(
this);
787 const CFX_PointF& point,
788 const CFX_Vector& delta) {
792 ObservedPtr<CPDFSDK_Widget> observer(
this);
794 nFlags
, point
, delta
);
798 const CFX_PointF& point) {
802 ObservedPtr<CPDFSDK_Widget> observer(
this);
808 const CFX_PointF& point) {
812 ObservedPtr<CPDFSDK_Widget> observer(
this);
817bool CPDFSDK_Widget::
OnChar(uint32_t nChar,
Mask<FWL_EVENTFLAG> nFlags) {
819 GetInteractiveFormFiller()
->OnChar(this, nChar
, nFlags
);
823 Mask<FWL_EVENTFLAG> nFlags) {
835 ObservedPtr<CPDFSDK_Widget> observer(
this);
846 ObservedPtr<CPDFSDK_Widget> observer(
this);
898 ObservedPtr<CPDFSDK_Widget> observer(
this);
900 observer
, index
, selected
);
904 ObservedPtr<CPDFSDK_Widget> observer(
this);
933 m_pInteractiveForm->UpdateField(pFormField);
937 CPDFSDK_PageView* pPageView) {
939 if (!m_pInteractiveForm->IsNeedHighLight(fieldType))
945 page2device.Transform(CFX_PointF(rcDevice.left, rcDevice.bottom));
946 rcDevice
.left = tmp.x;
951 rcDevice
.top = tmp.y;
956 AlphaAndColorRefToArgb(
957 static_cast<
int>(m_pInteractiveForm->GetHighlightAlpha()),
958 m_pInteractiveForm->GetHighlightColor(fieldType)));
967 fBorderWidth *= 2.0f;
1024 absl::optional<CFX_Color> crText =
1025 pFormCtrl->GetDefaultAppearance().GetColor();
1026 return crText.value_or(CFX_Color(CFX_Color::Type::kGray, 0));
1041 const CPDFSDK_PageView* pPageView) {
1044#ifdef PDF_ENABLE_XFA
1045 if (HandleXFAAAction(type, data, pFormFillEnv))
1060 if (!IsAppearanceValid())
1061 ResetAppearance(absl::nullopt, CPDFSDK_Widget::kValueUnchanged);
1067 absl::optional<WideString> sValue = OnFormat();
1071 if (sValue.has_value() && field_type == FormFieldType::kComboBox)
1072 ResetAppearance(sValue, CPDFSDK_Widget::kValueUnchanged);
1075#ifdef PDF_ENABLE_XFA
1076 auto* pContext = GetPageView()->GetFormFillEnv()->GetDocExtension();
1077 if (pContext && pContext->ContainsExtensionForegroundForm()) {
1078 if (!IsAppearanceValid() && !GetValue().IsEmpty())
1079 ResetXFAAppearance(CPDFSDK_Widget::kValueUnchanged);
1111 return CPDF_Action(
nullptr);
1114CFFL_InteractiveFormFiller* CPDFSDK_Widget::GetInteractiveFormFiller() {
1115 return GetPageView()->GetFormFillEnv()->GetInteractiveFormFiller();
bool Contains(const CFX_PointF &point) const
constexpr CFX_FloatRect(float l, float b, float r, float t)
constexpr CFX_FloatRect()=default
CFX_FloatRect & operator=(const CFX_FloatRect &that)=default
CFX_FloatRect GetDeflated(float x, float y) const
CFX_Matrix & operator=(const CFX_Matrix &other)=default
CFX_Matrix(float a1, float b1, float c1, float d1, float e1, float f1)
CFX_PointF Transform(const CFX_PointF &point) const
void AppendFloatRect(const CFX_FloatRect &rect)
bool DrawPath(const CFX_Path &path, const CFX_Matrix *pObject2Device, const CFX_GraphStateData *pGraphState, uint32_t fill_color, uint32_t stroke_color, const CFX_FillRenderOptions &fill_options)
CPDFSDK_PageView * GetPageView() const
const CPDF_Dictionary * GetAnnotDict() const
CPDF_Annot * GetPDFAnnot() const override
virtual void DrawAppearance(CFX_RenderDevice *pDevice, const CFX_Matrix &mtUser2Device, CPDF_Annot::AppearanceMode mode)
CPDFSDK_BAAnnot(CPDF_Annot *pAnnot, CPDFSDK_PageView *pPageView)
BorderStyle GetBorderStyle() const
int GetBorderWidth() const
virtual bool IsAppearanceValid()
CFX_FloatRect GetRect() const override
ByteString GetAppState() const
bool IsFocusableAnnot(const CPDF_Annot::Subtype &annot_type) const
RetainPtr< CPDF_Dictionary > GetMutableAnnotDict()
CPDFSDK_FormFillEnvironment * GetFormFillEnv() const
const CFX_Matrix & GetCurrentMatrix() const
CPDF_Action GetAction(AActionType eType) const
RetainPtr< const CPDF_Stream > GetStreamFor(const ByteString &key) const
FX_COLORREF ArgbToColorRef(FX_ARGB argb)
constexpr uint32_t kModifyAnnotation
constexpr uint32_t kFillForm
static constexpr CFX_FillRenderOptions EvenOddOptions()