7#include "fpdfsdk/cpdfsdk_interactiveform.h"
17#include "constants/annotation_flags.h"
18#include "core/fpdfapi/page/cpdf_page.h"
19#include "core/fpdfapi/parser/cfdf_document.h"
20#include "core/fpdfapi/parser/cpdf_array.h"
21#include "core/fpdfapi/parser/cpdf_dictionary.h"
22#include "core/fpdfapi/parser/cpdf_document.h"
23#include "core/fpdfapi/parser/cpdf_stream.h"
24#include "core/fpdfdoc/cpdf_action.h"
25#include "core/fpdfdoc/cpdf_formcontrol.h"
26#include "core/fpdfdoc/cpdf_interactiveform.h"
27#include "core/fxcrt/autorestorer.h"
28#include "core/fxcrt/fx_string_wrappers.h"
29#include "core/fxcrt/stl_util.h"
30#include "core/fxge/cfx_graphstatedata.h"
31#include "core/fxge/cfx_path.h"
32#include "fpdfsdk/cpdfsdk_annot.h"
33#include "fpdfsdk/cpdfsdk_annotiterator.h"
34#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
35#include "fpdfsdk/cpdfsdk_pageview.h"
36#include "fpdfsdk/cpdfsdk_widget.h"
37#include "fpdfsdk/formfiller/cffl_formfield.h"
38#include "fxjs/ijs_event_context.h"
39#include "fxjs/ijs_runtime.h"
40#include "third_party/base/check.h"
57bool IsFormFieldTypeXFA(FormFieldType fieldType) {
59 case FormFieldType::kXFA:
60 case FormFieldType::kXFA_CheckBox:
61 case FormFieldType::kXFA_ComboBox:
62 case FormFieldType::kXFA_ImageField:
63 case FormFieldType::kXFA_ListBox:
64 case FormFieldType::kXFA_PushButton:
65 case FormFieldType::kXFA_Signature:
66 case FormFieldType::kXFA_TextField:
74ByteString FDFToURLEncodedData(ByteString buffer) {
75 std::unique_ptr<CFDF_Document> pFDF =
76 CFDF_Document::ParseMemory(buffer.raw_span());
80 RetainPtr<
const CPDF_Dictionary> pMainDict =
81 pFDF->GetRoot()->GetDictFor(
"FDF");
85 RetainPtr<
const CPDF_Array> pFields = pMainDict->GetArrayFor(
"Fields");
89 fxcrt::ostringstream encoded_data;
90 for (uint32_t i = 0; i < pFields->size(); i++) {
91 RetainPtr<
const CPDF_Dictionary> pField = pFields->GetDictAt(i);
94 WideString name = pField->GetUnicodeTextFor(
"T");
96 ByteString csBValue = pField->GetByteStringFor(
"V");
97 WideString csWValue = PDF_DecodeText(csBValue.raw_span());
99 encoded_data << name_b <<
"=" << csValue_b;
100 if (i != pFields->size() - 1)
104 return ByteString(encoded_data);
110 CPDFSDK_FormFillEnvironment* pFormFillEnv)
114 m_pInteractiveForm->SetNotifierIface(
this);
125 CPDFSDK_Widget* pWidget =
nullptr;
126 const auto it = m_Map.find(pControl);
127 if (it != m_Map.end())
128 pWidget = it->second;
133 CPDFSDK_PageView* pPage =
nullptr;
134 RetainPtr<
const CPDF_Dictionary> pControlDict = pControl->GetWidgetDict();
135 RetainPtr<
const CPDF_Dictionary> pPageDict = pControlDict->GetDictFor(
"P");
139 pPage = m_pFormFillEnv->GetPageViewAtIndex(nPageIndex);
143 int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
145 pPage = m_pFormFillEnv->GetPageViewAtIndex(nPageIndex);
152 const WideString& sFieldName,
153 std::vector<ObservedPtr<CPDFSDK_Widget>>* widgets)
const {
154 for (size_t i = 0, sz = m_pInteractiveForm->CountFields(sFieldName); i < sz;
156 CPDF_FormField* pFormField = m_pInteractiveForm->GetField(i, sFieldName);
158 GetWidgets(pFormField, widgets);
164 std::vector<ObservedPtr<CPDFSDK_Widget>>* widgets)
const {
170 widgets->emplace_back(pWidget);
174int CPDFSDK_InteractiveForm::GetPageIndexByAnnotDict(
176 const CPDF_Dictionary* pAnnotDict)
const {
180 RetainPtr<
const CPDF_Dictionary> pPageDict =
181 pDocument->GetPageDictionary(i);
185 RetainPtr<
const CPDF_Array> pAnnots = pPageDict->GetArrayFor(
"Annots");
189 for (size_t j = 0, jsz = pAnnots->size(); j < jsz; j++) {
190 RetainPtr<
const CPDF_Object> pDict = pAnnots->GetDirectObjectAt(j);
191 if (pAnnotDict == pDict)
199 CPDFSDK_Widget* pWidget) {
200 m_Map[pdfium::WrapUnowned(pControl)] = pWidget;
204 auto it = m_Map.find(pControl);
205 if (it != m_Map.end())
210 m_bCalculate = bEnabled;
218void CPDFSDK_InteractiveForm::XfaEnableCalculate(
bool bEnabled) {
219 m_bXfaCalculate = bEnabled;
222bool CPDFSDK_InteractiveForm::IsXfaCalculateEnabled()
const {
223 return m_bXfaCalculate;
226bool CPDFSDK_InteractiveForm::IsXfaValidationsEnabled() {
227 return m_bXfaValidationsEnabled;
229void CPDFSDK_InteractiveForm::XfaSetValidationsEnabled(
bool bEnabled) {
230 m_bXfaValidationsEnabled = bEnabled;
233void CPDFSDK_InteractiveForm::SynchronizeField(CPDF_FormField* pFormField) {
234 for (
int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
235 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
236 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
237 pWidget->Synchronize(
false);
243 if (!m_pFormFillEnv->IsJSPlatformPresent())
255 IJS_Runtime* pRuntime = m_pFormFillEnv->GetIJSRuntime();
256 int nSize = m_pInteractiveForm->CountFieldsInCalculationOrder();
257 for (
int i = 0; i < nSize; i++) {
258 CPDF_FormField* pField = m_pInteractiveForm->GetFieldInCalculationOrder(i);
263 if (!IsFormFieldTypeComboOrText(fieldType))
279 WideString sValue = sOldValue;
284 absl::optional<IJS_Runtime::JS_Error> err = pContext->RunScript(csJS);
285 if (!err.has_value() && bRC && sValue != sOldValue)
292 if (!m_pFormFillEnv->IsJSPlatformPresent())
293 return absl::nullopt;
296 IJS_Runtime* pRuntime = m_pFormFillEnv->GetIJSRuntime();
312 absl::optional<IJS_Runtime::JS_Error> err = pContext->RunScript(script);
313 if (!err.has_value())
318 return absl::nullopt;
323 absl::optional<WideString> sValue) {
327 if (CPDFSDK_Widget* pWidget =
GetWidget(pFormCtrl
))
333 auto* formfiller = m_pFormFillEnv->GetInteractiveFormFiller();
344 formfiller->GetViewBBox(m_pFormFillEnv->GetPageView(pPage), pWidget);
345 m_pFormFillEnv->Invalidate(pPage, rect);
350 const WideString& csValue) {
363 m_pFormFillEnv->DoActionFieldJavaScript(action, CPDF_AAction::kKeyStroke,
369 const WideString& csValue) {
382 m_pFormFillEnv->DoActionFieldJavaScript(action, CPDF_AAction::kValidate,
388 DCHECK(action.GetDict());
389 std::vector<CPDF_FormField*> fields =
390 GetFieldFromObjects(action.GetAllFields());
392 bool bChanged =
false;
394 for (CPDF_FormField* pField : fields) {
395 for (
int i = 0, sz = pField->CountControls(); i < sz; ++i) {
396 CPDF_FormControl* pControl = pField->GetControl(i);
399 if (CPDFSDK_Widget* pWidget = GetWidget(pControl)) {
400 uint32_t nFlags = pWidget->GetFlags();
401 nFlags &= ~pdfium::annotation_flags::kInvisible;
402 nFlags &= ~pdfium::annotation_flags::kNoView;
404 nFlags |= pdfium::annotation_flags::kHidden;
406 nFlags &= ~pdfium::annotation_flags::kHidden;
407 pWidget->SetFlags(nFlags);
408 pWidget->GetPageView()->UpdateView(pWidget);
424 std::vector<CPDF_FormField*> fields =
425 GetFieldFromObjects(action.GetAllFields());
426 if (!fields.empty()) {
427 bool bIncludeOrExclude = !(dwFlags & 0x01);
428 if (!m_pInteractiveForm->CheckRequiredFields(&fields, bIncludeOrExclude))
431 return SubmitFields(sDestination, fields, bIncludeOrExclude,
false);
434 if (!m_pInteractiveForm->CheckRequiredFields(
nullptr,
true))
441 const WideString& csDestination,
442 const std::vector<CPDF_FormField*>& fields,
443 bool bIncludeOrExclude,
445 ByteString text_buf = ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude);
450 text_buf
= FDFToURLEncodedData(text_buf);
455 m_pFormFillEnv->SubmitForm(text_buf.raw_span(), csDestination);
460 const std::vector<CPDF_FormField*>& fields,
461 bool bIncludeOrExclude) {
462 std::unique_ptr<CFDF_Document> pFDF = m_pInteractiveForm->ExportToFDF(
463 m_pFormFillEnv->GetFilePath(), fields, bIncludeOrExclude);
465 return pFDF ? pFDF->WriteToString() : ByteString
();
468bool CPDFSDK_InteractiveForm::
SubmitForm(
const WideString& sDestination) {
472 std::unique_ptr<CFDF_Document> pFDFDoc =
473 m_pInteractiveForm->ExportToFDF(m_pFormFillEnv->GetFilePath());
477 ByteString fdf_buffer = pFDFDoc->WriteToString();
481 m_pFormFillEnv->SubmitForm(fdf_buffer.raw_span(), sDestination);
486 std::unique_ptr<CFDF_Document> pFDF =
487 m_pInteractiveForm->ExportToFDF(m_pFormFillEnv->GetFilePath());
489 return pFDF ? pFDF->WriteToString() : ByteString
();
493 DCHECK(action.GetDict());
495 m_pInteractiveForm->ResetForm();
499 std::vector<CPDF_FormField*> fields =
500 GetFieldFromObjects(action.GetAllFields());
501 m_pInteractiveForm->ResetForm(fields, !(dwFlags & 0x01));
505 const std::vector<RetainPtr<
const CPDF_Object>>& objects)
const {
506 std::vector<CPDF_FormField*> fields;
507 for (
const CPDF_Object* pObject : objects) {
508 if (!pObject || !pObject->IsString())
511 WideString csName = pObject->GetUnicodeText();
512 CPDF_FormField* pField = m_pInteractiveForm->GetField(0, csName);
514 fields.push_back(pField);
520 const WideString& csValue) {
522 if (!IsFormFieldTypeComboOrText(fieldType))
531 SynchronizeField(pField);
535 if (!IsFormFieldTypeComboOrText(fieldType))
539 ResetFieldAppearance(pField, OnFormat(pField));
544 const WideString& csValue) {
557 ResetFieldAppearance(pField, absl::nullopt);
582 if (IsFormFieldTypeXFA(fieldType)) {
583 if (!m_NeedsHighlight[
static_cast<size_t>(fieldType)])
584 return m_NeedsHighlight[
static_cast<size_t>(FormFieldType::kXFA)];
587 return m_NeedsHighlight[
static_cast<size_t>(fieldType)];
591 std::fill(std::begin(m_HighlightColor), std::end(m_HighlightColor),
593 std::fill(std::begin(m_NeedsHighlight), std::end(m_NeedsHighlight),
false);
601 m_HighlightColor[
static_cast<size_t>(fieldType)] = clr;
602 m_NeedsHighlight[
static_cast<size_t>(fieldType)] =
true;
606 for (size_t i = 0; i < kFormFieldTypeCount; ++i) {
607 m_HighlightColor[i] = clr;
608 m_NeedsHighlight[i] =
true;
620 if (IsFormFieldTypeXFA(fieldType)) {
621 if (!m_NeedsHighlight[
static_cast<size_t>(fieldType)] &&
622 m_NeedsHighlight[
static_cast<size_t>(FormFieldType::kXFA)]) {
623 return m_HighlightColor[
static_cast<size_t>(FormFieldType::kXFA)];
627 return m_HighlightColor[
static_cast<size_t>(fieldType)];
CPDFSDK_Annot * GetAnnotByDict(const CPDF_Dictionary *pDict)
bool ActionExist(AActionType eType) const
CPDF_Action GetAction(AActionType eType) const
WideString GetFilePath() const
uint32_t GetFlags() const
bool GetHideStatus() const
WideString GetJavaScript() const
int GetPageIndex(uint32_t objnum)
virtual void OnField_Format(CPDF_FormField *pTarget, WideString *Value)=0
virtual void OnField_Calculate(CPDF_FormField *pSource, CPDF_FormField *pTarget, WideString *Value, bool *bRc)=0
IJS_EventContext * operator->() const
ScopedEventContext(IJS_Runtime *pRuntime)
ByteString & operator=(ByteString &&that) noexcept
WideString & operator=(WideString &&that) noexcept
ByteString ToDefANSI() const
constexpr uint32_t FXSYS_BGR(uint8_t b, uint8_t g, uint8_t r)