1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2016 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_interactiveform.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <stdint.h>
10*3ac0a46fSAndroid Build Coastguard Worker
11*3ac0a46fSAndroid Build Coastguard Worker #include <algorithm>
12*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
13*3ac0a46fSAndroid Build Coastguard Worker #include <sstream>
14*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
15*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
16*3ac0a46fSAndroid Build Coastguard Worker
17*3ac0a46fSAndroid Build Coastguard Worker #include "constants/annotation_flags.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/page/cpdf_page.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cfdf_document.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_array.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_dictionary.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_document.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_stream.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_action.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_formcontrol.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_interactiveform.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/autorestorer.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_string_wrappers.h"
29*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/stl_util.h"
30*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_graphstatedata.h"
31*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_path.h"
32*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_annot.h"
33*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_annotiterator.h"
34*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
35*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_pageview.h"
36*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_widget.h"
37*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/formfiller/cffl_formfield.h"
38*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/ijs_event_context.h"
39*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/ijs_runtime.h"
40*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
41*3ac0a46fSAndroid Build Coastguard Worker
42*3ac0a46fSAndroid Build Coastguard Worker namespace {
43*3ac0a46fSAndroid Build Coastguard Worker
44*3ac0a46fSAndroid Build Coastguard Worker constexpr uint32_t kWhiteBGR = FXSYS_BGR(255, 255, 255);
45*3ac0a46fSAndroid Build Coastguard Worker
IsFormFieldTypeComboOrText(FormFieldType fieldType)46*3ac0a46fSAndroid Build Coastguard Worker bool IsFormFieldTypeComboOrText(FormFieldType fieldType) {
47*3ac0a46fSAndroid Build Coastguard Worker switch (fieldType) {
48*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kComboBox:
49*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kTextField:
50*3ac0a46fSAndroid Build Coastguard Worker return true;
51*3ac0a46fSAndroid Build Coastguard Worker default:
52*3ac0a46fSAndroid Build Coastguard Worker return false;
53*3ac0a46fSAndroid Build Coastguard Worker }
54*3ac0a46fSAndroid Build Coastguard Worker }
55*3ac0a46fSAndroid Build Coastguard Worker
56*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
IsFormFieldTypeXFA(FormFieldType fieldType)57*3ac0a46fSAndroid Build Coastguard Worker bool IsFormFieldTypeXFA(FormFieldType fieldType) {
58*3ac0a46fSAndroid Build Coastguard Worker switch (fieldType) {
59*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kXFA:
60*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kXFA_CheckBox:
61*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kXFA_ComboBox:
62*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kXFA_ImageField:
63*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kXFA_ListBox:
64*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kXFA_PushButton:
65*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kXFA_Signature:
66*3ac0a46fSAndroid Build Coastguard Worker case FormFieldType::kXFA_TextField:
67*3ac0a46fSAndroid Build Coastguard Worker return true;
68*3ac0a46fSAndroid Build Coastguard Worker default:
69*3ac0a46fSAndroid Build Coastguard Worker return false;
70*3ac0a46fSAndroid Build Coastguard Worker }
71*3ac0a46fSAndroid Build Coastguard Worker }
72*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
73*3ac0a46fSAndroid Build Coastguard Worker
FDFToURLEncodedData(ByteString buffer)74*3ac0a46fSAndroid Build Coastguard Worker ByteString FDFToURLEncodedData(ByteString buffer) {
75*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFDF_Document> pFDF =
76*3ac0a46fSAndroid Build Coastguard Worker CFDF_Document::ParseMemory(buffer.raw_span());
77*3ac0a46fSAndroid Build Coastguard Worker if (!pFDF)
78*3ac0a46fSAndroid Build Coastguard Worker return buffer;
79*3ac0a46fSAndroid Build Coastguard Worker
80*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pMainDict =
81*3ac0a46fSAndroid Build Coastguard Worker pFDF->GetRoot()->GetDictFor("FDF");
82*3ac0a46fSAndroid Build Coastguard Worker if (!pMainDict)
83*3ac0a46fSAndroid Build Coastguard Worker return ByteString();
84*3ac0a46fSAndroid Build Coastguard Worker
85*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Array> pFields = pMainDict->GetArrayFor("Fields");
86*3ac0a46fSAndroid Build Coastguard Worker if (!pFields)
87*3ac0a46fSAndroid Build Coastguard Worker return ByteString();
88*3ac0a46fSAndroid Build Coastguard Worker
89*3ac0a46fSAndroid Build Coastguard Worker fxcrt::ostringstream encoded_data;
90*3ac0a46fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < pFields->size(); i++) {
91*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pField = pFields->GetDictAt(i);
92*3ac0a46fSAndroid Build Coastguard Worker if (!pField)
93*3ac0a46fSAndroid Build Coastguard Worker continue;
94*3ac0a46fSAndroid Build Coastguard Worker WideString name = pField->GetUnicodeTextFor("T");
95*3ac0a46fSAndroid Build Coastguard Worker ByteString name_b = name.ToDefANSI();
96*3ac0a46fSAndroid Build Coastguard Worker ByteString csBValue = pField->GetByteStringFor("V");
97*3ac0a46fSAndroid Build Coastguard Worker WideString csWValue = PDF_DecodeText(csBValue.raw_span());
98*3ac0a46fSAndroid Build Coastguard Worker ByteString csValue_b = csWValue.ToDefANSI();
99*3ac0a46fSAndroid Build Coastguard Worker encoded_data << name_b << "=" << csValue_b;
100*3ac0a46fSAndroid Build Coastguard Worker if (i != pFields->size() - 1)
101*3ac0a46fSAndroid Build Coastguard Worker encoded_data << "&";
102*3ac0a46fSAndroid Build Coastguard Worker }
103*3ac0a46fSAndroid Build Coastguard Worker
104*3ac0a46fSAndroid Build Coastguard Worker return ByteString(encoded_data);
105*3ac0a46fSAndroid Build Coastguard Worker }
106*3ac0a46fSAndroid Build Coastguard Worker
107*3ac0a46fSAndroid Build Coastguard Worker } // namespace
108*3ac0a46fSAndroid Build Coastguard Worker
CPDFSDK_InteractiveForm(CPDFSDK_FormFillEnvironment * pFormFillEnv)109*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm::CPDFSDK_InteractiveForm(
110*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv)
111*3ac0a46fSAndroid Build Coastguard Worker : m_pFormFillEnv(pFormFillEnv),
112*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm(std::make_unique<CPDF_InteractiveForm>(
113*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->GetPDFDocument())) {
114*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->SetNotifierIface(this);
115*3ac0a46fSAndroid Build Coastguard Worker RemoveAllHighLights();
116*3ac0a46fSAndroid Build Coastguard Worker }
117*3ac0a46fSAndroid Build Coastguard Worker
118*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm::~CPDFSDK_InteractiveForm() = default;
119*3ac0a46fSAndroid Build Coastguard Worker
GetWidget(CPDF_FormControl * pControl) const120*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Widget* CPDFSDK_InteractiveForm::GetWidget(
121*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormControl* pControl) const {
122*3ac0a46fSAndroid Build Coastguard Worker if (!pControl)
123*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
124*3ac0a46fSAndroid Build Coastguard Worker
125*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Widget* pWidget = nullptr;
126*3ac0a46fSAndroid Build Coastguard Worker const auto it = m_Map.find(pControl);
127*3ac0a46fSAndroid Build Coastguard Worker if (it != m_Map.end())
128*3ac0a46fSAndroid Build Coastguard Worker pWidget = it->second;
129*3ac0a46fSAndroid Build Coastguard Worker if (pWidget)
130*3ac0a46fSAndroid Build Coastguard Worker return pWidget;
131*3ac0a46fSAndroid Build Coastguard Worker
132*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument();
133*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* pPage = nullptr;
134*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pControlDict = pControl->GetWidgetDict();
135*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pPageDict = pControlDict->GetDictFor("P");
136*3ac0a46fSAndroid Build Coastguard Worker if (pPageDict) {
137*3ac0a46fSAndroid Build Coastguard Worker int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
138*3ac0a46fSAndroid Build Coastguard Worker if (nPageIndex >= 0)
139*3ac0a46fSAndroid Build Coastguard Worker pPage = m_pFormFillEnv->GetPageViewAtIndex(nPageIndex);
140*3ac0a46fSAndroid Build Coastguard Worker }
141*3ac0a46fSAndroid Build Coastguard Worker
142*3ac0a46fSAndroid Build Coastguard Worker if (!pPage) {
143*3ac0a46fSAndroid Build Coastguard Worker int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
144*3ac0a46fSAndroid Build Coastguard Worker if (nPageIndex >= 0)
145*3ac0a46fSAndroid Build Coastguard Worker pPage = m_pFormFillEnv->GetPageViewAtIndex(nPageIndex);
146*3ac0a46fSAndroid Build Coastguard Worker }
147*3ac0a46fSAndroid Build Coastguard Worker
148*3ac0a46fSAndroid Build Coastguard Worker return pPage ? ToCPDFSDKWidget(pPage->GetAnnotByDict(pControlDict)) : nullptr;
149*3ac0a46fSAndroid Build Coastguard Worker }
150*3ac0a46fSAndroid Build Coastguard Worker
GetWidgets(const WideString & sFieldName,std::vector<ObservedPtr<CPDFSDK_Widget>> * widgets) const151*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::GetWidgets(
152*3ac0a46fSAndroid Build Coastguard Worker const WideString& sFieldName,
153*3ac0a46fSAndroid Build Coastguard Worker std::vector<ObservedPtr<CPDFSDK_Widget>>* widgets) const {
154*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0, sz = m_pInteractiveForm->CountFields(sFieldName); i < sz;
155*3ac0a46fSAndroid Build Coastguard Worker ++i) {
156*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pFormField = m_pInteractiveForm->GetField(i, sFieldName);
157*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pFormField);
158*3ac0a46fSAndroid Build Coastguard Worker GetWidgets(pFormField, widgets);
159*3ac0a46fSAndroid Build Coastguard Worker }
160*3ac0a46fSAndroid Build Coastguard Worker }
161*3ac0a46fSAndroid Build Coastguard Worker
GetWidgets(CPDF_FormField * pField,std::vector<ObservedPtr<CPDFSDK_Widget>> * widgets) const162*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::GetWidgets(
163*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pField,
164*3ac0a46fSAndroid Build Coastguard Worker std::vector<ObservedPtr<CPDFSDK_Widget>>* widgets) const {
165*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
166*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormControl* pFormCtrl = pField->GetControl(i);
167*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pFormCtrl);
168*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
169*3ac0a46fSAndroid Build Coastguard Worker if (pWidget)
170*3ac0a46fSAndroid Build Coastguard Worker widgets->emplace_back(pWidget);
171*3ac0a46fSAndroid Build Coastguard Worker }
172*3ac0a46fSAndroid Build Coastguard Worker }
173*3ac0a46fSAndroid Build Coastguard Worker
GetPageIndexByAnnotDict(CPDF_Document * pDocument,const CPDF_Dictionary * pAnnotDict) const174*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_InteractiveForm::GetPageIndexByAnnotDict(
175*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDocument,
176*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pAnnotDict) const {
177*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pAnnotDict);
178*3ac0a46fSAndroid Build Coastguard Worker
179*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
180*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pPageDict =
181*3ac0a46fSAndroid Build Coastguard Worker pDocument->GetPageDictionary(i);
182*3ac0a46fSAndroid Build Coastguard Worker if (!pPageDict)
183*3ac0a46fSAndroid Build Coastguard Worker continue;
184*3ac0a46fSAndroid Build Coastguard Worker
185*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Array> pAnnots = pPageDict->GetArrayFor("Annots");
186*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnots)
187*3ac0a46fSAndroid Build Coastguard Worker continue;
188*3ac0a46fSAndroid Build Coastguard Worker
189*3ac0a46fSAndroid Build Coastguard Worker for (size_t j = 0, jsz = pAnnots->size(); j < jsz; j++) {
190*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Object> pDict = pAnnots->GetDirectObjectAt(j);
191*3ac0a46fSAndroid Build Coastguard Worker if (pAnnotDict == pDict)
192*3ac0a46fSAndroid Build Coastguard Worker return i;
193*3ac0a46fSAndroid Build Coastguard Worker }
194*3ac0a46fSAndroid Build Coastguard Worker }
195*3ac0a46fSAndroid Build Coastguard Worker return -1;
196*3ac0a46fSAndroid Build Coastguard Worker }
197*3ac0a46fSAndroid Build Coastguard Worker
AddMap(CPDF_FormControl * pControl,CPDFSDK_Widget * pWidget)198*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::AddMap(CPDF_FormControl* pControl,
199*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Widget* pWidget) {
200*3ac0a46fSAndroid Build Coastguard Worker m_Map[pdfium::WrapUnowned(pControl)] = pWidget;
201*3ac0a46fSAndroid Build Coastguard Worker }
202*3ac0a46fSAndroid Build Coastguard Worker
RemoveMap(CPDF_FormControl * pControl)203*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::RemoveMap(CPDF_FormControl* pControl) {
204*3ac0a46fSAndroid Build Coastguard Worker auto it = m_Map.find(pControl);
205*3ac0a46fSAndroid Build Coastguard Worker if (it != m_Map.end())
206*3ac0a46fSAndroid Build Coastguard Worker m_Map.erase(it);
207*3ac0a46fSAndroid Build Coastguard Worker }
208*3ac0a46fSAndroid Build Coastguard Worker
EnableCalculate(bool bEnabled)209*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::EnableCalculate(bool bEnabled) {
210*3ac0a46fSAndroid Build Coastguard Worker m_bCalculate = bEnabled;
211*3ac0a46fSAndroid Build Coastguard Worker }
212*3ac0a46fSAndroid Build Coastguard Worker
IsCalculateEnabled() const213*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::IsCalculateEnabled() const {
214*3ac0a46fSAndroid Build Coastguard Worker return m_bCalculate;
215*3ac0a46fSAndroid Build Coastguard Worker }
216*3ac0a46fSAndroid Build Coastguard Worker
217*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
XfaEnableCalculate(bool bEnabled)218*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::XfaEnableCalculate(bool bEnabled) {
219*3ac0a46fSAndroid Build Coastguard Worker m_bXfaCalculate = bEnabled;
220*3ac0a46fSAndroid Build Coastguard Worker }
221*3ac0a46fSAndroid Build Coastguard Worker
IsXfaCalculateEnabled() const222*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::IsXfaCalculateEnabled() const {
223*3ac0a46fSAndroid Build Coastguard Worker return m_bXfaCalculate;
224*3ac0a46fSAndroid Build Coastguard Worker }
225*3ac0a46fSAndroid Build Coastguard Worker
IsXfaValidationsEnabled()226*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::IsXfaValidationsEnabled() {
227*3ac0a46fSAndroid Build Coastguard Worker return m_bXfaValidationsEnabled;
228*3ac0a46fSAndroid Build Coastguard Worker }
XfaSetValidationsEnabled(bool bEnabled)229*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::XfaSetValidationsEnabled(bool bEnabled) {
230*3ac0a46fSAndroid Build Coastguard Worker m_bXfaValidationsEnabled = bEnabled;
231*3ac0a46fSAndroid Build Coastguard Worker }
232*3ac0a46fSAndroid Build Coastguard Worker
SynchronizeField(CPDF_FormField * pFormField)233*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::SynchronizeField(CPDF_FormField* pFormField) {
234*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
235*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
236*3ac0a46fSAndroid Build Coastguard Worker if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
237*3ac0a46fSAndroid Build Coastguard Worker pWidget->Synchronize(false);
238*3ac0a46fSAndroid Build Coastguard Worker }
239*3ac0a46fSAndroid Build Coastguard Worker }
240*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
241*3ac0a46fSAndroid Build Coastguard Worker
OnCalculate(CPDF_FormField * pFormField)242*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::OnCalculate(CPDF_FormField* pFormField) {
243*3ac0a46fSAndroid Build Coastguard Worker if (!m_pFormFillEnv->IsJSPlatformPresent())
244*3ac0a46fSAndroid Build Coastguard Worker return;
245*3ac0a46fSAndroid Build Coastguard Worker
246*3ac0a46fSAndroid Build Coastguard Worker if (m_bBusy)
247*3ac0a46fSAndroid Build Coastguard Worker return;
248*3ac0a46fSAndroid Build Coastguard Worker
249*3ac0a46fSAndroid Build Coastguard Worker AutoRestorer<bool> restorer(&m_bBusy);
250*3ac0a46fSAndroid Build Coastguard Worker m_bBusy = true;
251*3ac0a46fSAndroid Build Coastguard Worker
252*3ac0a46fSAndroid Build Coastguard Worker if (!IsCalculateEnabled())
253*3ac0a46fSAndroid Build Coastguard Worker return;
254*3ac0a46fSAndroid Build Coastguard Worker
255*3ac0a46fSAndroid Build Coastguard Worker IJS_Runtime* pRuntime = m_pFormFillEnv->GetIJSRuntime();
256*3ac0a46fSAndroid Build Coastguard Worker int nSize = m_pInteractiveForm->CountFieldsInCalculationOrder();
257*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0; i < nSize; i++) {
258*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pField = m_pInteractiveForm->GetFieldInCalculationOrder(i);
259*3ac0a46fSAndroid Build Coastguard Worker if (!pField)
260*3ac0a46fSAndroid Build Coastguard Worker continue;
261*3ac0a46fSAndroid Build Coastguard Worker
262*3ac0a46fSAndroid Build Coastguard Worker FormFieldType fieldType = pField->GetFieldType();
263*3ac0a46fSAndroid Build Coastguard Worker if (!IsFormFieldTypeComboOrText(fieldType))
264*3ac0a46fSAndroid Build Coastguard Worker continue;
265*3ac0a46fSAndroid Build Coastguard Worker
266*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction aAction = pField->GetAdditionalAction();
267*3ac0a46fSAndroid Build Coastguard Worker if (!aAction.ActionExist(CPDF_AAction::kCalculate))
268*3ac0a46fSAndroid Build Coastguard Worker continue;
269*3ac0a46fSAndroid Build Coastguard Worker
270*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action action = aAction.GetAction(CPDF_AAction::kCalculate);
271*3ac0a46fSAndroid Build Coastguard Worker if (!action.HasDict())
272*3ac0a46fSAndroid Build Coastguard Worker continue;
273*3ac0a46fSAndroid Build Coastguard Worker
274*3ac0a46fSAndroid Build Coastguard Worker WideString csJS = action.GetJavaScript();
275*3ac0a46fSAndroid Build Coastguard Worker if (csJS.IsEmpty())
276*3ac0a46fSAndroid Build Coastguard Worker continue;
277*3ac0a46fSAndroid Build Coastguard Worker
278*3ac0a46fSAndroid Build Coastguard Worker WideString sOldValue = pField->GetValue();
279*3ac0a46fSAndroid Build Coastguard Worker WideString sValue = sOldValue;
280*3ac0a46fSAndroid Build Coastguard Worker bool bRC = true;
281*3ac0a46fSAndroid Build Coastguard Worker IJS_Runtime::ScopedEventContext pContext(pRuntime);
282*3ac0a46fSAndroid Build Coastguard Worker pContext->OnField_Calculate(pFormField, pField, &sValue, &bRC);
283*3ac0a46fSAndroid Build Coastguard Worker
284*3ac0a46fSAndroid Build Coastguard Worker absl::optional<IJS_Runtime::JS_Error> err = pContext->RunScript(csJS);
285*3ac0a46fSAndroid Build Coastguard Worker if (!err.has_value() && bRC && sValue != sOldValue)
286*3ac0a46fSAndroid Build Coastguard Worker pField->SetValue(sValue, NotificationOption::kNotify);
287*3ac0a46fSAndroid Build Coastguard Worker }
288*3ac0a46fSAndroid Build Coastguard Worker }
289*3ac0a46fSAndroid Build Coastguard Worker
OnFormat(CPDF_FormField * pFormField)290*3ac0a46fSAndroid Build Coastguard Worker absl::optional<WideString> CPDFSDK_InteractiveForm::OnFormat(
291*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pFormField) {
292*3ac0a46fSAndroid Build Coastguard Worker if (!m_pFormFillEnv->IsJSPlatformPresent())
293*3ac0a46fSAndroid Build Coastguard Worker return absl::nullopt;
294*3ac0a46fSAndroid Build Coastguard Worker
295*3ac0a46fSAndroid Build Coastguard Worker WideString sValue = pFormField->GetValue();
296*3ac0a46fSAndroid Build Coastguard Worker IJS_Runtime* pRuntime = m_pFormFillEnv->GetIJSRuntime();
297*3ac0a46fSAndroid Build Coastguard Worker if (pFormField->GetFieldType() == FormFieldType::kComboBox &&
298*3ac0a46fSAndroid Build Coastguard Worker pFormField->CountSelectedItems() > 0) {
299*3ac0a46fSAndroid Build Coastguard Worker int index = pFormField->GetSelectedIndex(0);
300*3ac0a46fSAndroid Build Coastguard Worker if (index >= 0)
301*3ac0a46fSAndroid Build Coastguard Worker sValue = pFormField->GetOptionLabel(index);
302*3ac0a46fSAndroid Build Coastguard Worker }
303*3ac0a46fSAndroid Build Coastguard Worker
304*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction aAction = pFormField->GetAdditionalAction();
305*3ac0a46fSAndroid Build Coastguard Worker if (aAction.ActionExist(CPDF_AAction::kFormat)) {
306*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action action = aAction.GetAction(CPDF_AAction::kFormat);
307*3ac0a46fSAndroid Build Coastguard Worker if (action.HasDict()) {
308*3ac0a46fSAndroid Build Coastguard Worker WideString script = action.GetJavaScript();
309*3ac0a46fSAndroid Build Coastguard Worker if (!script.IsEmpty()) {
310*3ac0a46fSAndroid Build Coastguard Worker IJS_Runtime::ScopedEventContext pContext(pRuntime);
311*3ac0a46fSAndroid Build Coastguard Worker pContext->OnField_Format(pFormField, &sValue);
312*3ac0a46fSAndroid Build Coastguard Worker absl::optional<IJS_Runtime::JS_Error> err = pContext->RunScript(script);
313*3ac0a46fSAndroid Build Coastguard Worker if (!err.has_value())
314*3ac0a46fSAndroid Build Coastguard Worker return sValue;
315*3ac0a46fSAndroid Build Coastguard Worker }
316*3ac0a46fSAndroid Build Coastguard Worker }
317*3ac0a46fSAndroid Build Coastguard Worker }
318*3ac0a46fSAndroid Build Coastguard Worker return absl::nullopt;
319*3ac0a46fSAndroid Build Coastguard Worker }
320*3ac0a46fSAndroid Build Coastguard Worker
ResetFieldAppearance(CPDF_FormField * pFormField,absl::optional<WideString> sValue)321*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::ResetFieldAppearance(
322*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pFormField,
323*3ac0a46fSAndroid Build Coastguard Worker absl::optional<WideString> sValue) {
324*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
325*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
326*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pFormCtrl);
327*3ac0a46fSAndroid Build Coastguard Worker if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
328*3ac0a46fSAndroid Build Coastguard Worker pWidget->ResetAppearance(sValue, CPDFSDK_Widget::kValueChanged);
329*3ac0a46fSAndroid Build Coastguard Worker }
330*3ac0a46fSAndroid Build Coastguard Worker }
331*3ac0a46fSAndroid Build Coastguard Worker
UpdateField(CPDF_FormField * pFormField)332*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::UpdateField(CPDF_FormField* pFormField) {
333*3ac0a46fSAndroid Build Coastguard Worker auto* formfiller = m_pFormFillEnv->GetInteractiveFormFiller();
334*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
335*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
336*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pFormCtrl);
337*3ac0a46fSAndroid Build Coastguard Worker
338*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
339*3ac0a46fSAndroid Build Coastguard Worker if (!pWidget)
340*3ac0a46fSAndroid Build Coastguard Worker continue;
341*3ac0a46fSAndroid Build Coastguard Worker
342*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* pPage = pWidget->GetPage();
343*3ac0a46fSAndroid Build Coastguard Worker FX_RECT rect =
344*3ac0a46fSAndroid Build Coastguard Worker formfiller->GetViewBBox(m_pFormFillEnv->GetPageView(pPage), pWidget);
345*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->Invalidate(pPage, rect);
346*3ac0a46fSAndroid Build Coastguard Worker }
347*3ac0a46fSAndroid Build Coastguard Worker }
348*3ac0a46fSAndroid Build Coastguard Worker
OnKeyStrokeCommit(CPDF_FormField * pFormField,const WideString & csValue)349*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
350*3ac0a46fSAndroid Build Coastguard Worker const WideString& csValue) {
351*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction aAction = pFormField->GetAdditionalAction();
352*3ac0a46fSAndroid Build Coastguard Worker if (!aAction.ActionExist(CPDF_AAction::kKeyStroke))
353*3ac0a46fSAndroid Build Coastguard Worker return true;
354*3ac0a46fSAndroid Build Coastguard Worker
355*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action action = aAction.GetAction(CPDF_AAction::kKeyStroke);
356*3ac0a46fSAndroid Build Coastguard Worker if (!action.HasDict())
357*3ac0a46fSAndroid Build Coastguard Worker return true;
358*3ac0a46fSAndroid Build Coastguard Worker
359*3ac0a46fSAndroid Build Coastguard Worker CFFL_FieldAction fa;
360*3ac0a46fSAndroid Build Coastguard Worker fa.bModifier = false;
361*3ac0a46fSAndroid Build Coastguard Worker fa.bShift = false;
362*3ac0a46fSAndroid Build Coastguard Worker fa.sValue = csValue;
363*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->DoActionFieldJavaScript(action, CPDF_AAction::kKeyStroke,
364*3ac0a46fSAndroid Build Coastguard Worker pFormField, &fa);
365*3ac0a46fSAndroid Build Coastguard Worker return fa.bRC;
366*3ac0a46fSAndroid Build Coastguard Worker }
367*3ac0a46fSAndroid Build Coastguard Worker
OnValidate(CPDF_FormField * pFormField,const WideString & csValue)368*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::OnValidate(CPDF_FormField* pFormField,
369*3ac0a46fSAndroid Build Coastguard Worker const WideString& csValue) {
370*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction aAction = pFormField->GetAdditionalAction();
371*3ac0a46fSAndroid Build Coastguard Worker if (!aAction.ActionExist(CPDF_AAction::kValidate))
372*3ac0a46fSAndroid Build Coastguard Worker return true;
373*3ac0a46fSAndroid Build Coastguard Worker
374*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action action = aAction.GetAction(CPDF_AAction::kValidate);
375*3ac0a46fSAndroid Build Coastguard Worker if (!action.HasDict())
376*3ac0a46fSAndroid Build Coastguard Worker return true;
377*3ac0a46fSAndroid Build Coastguard Worker
378*3ac0a46fSAndroid Build Coastguard Worker CFFL_FieldAction fa;
379*3ac0a46fSAndroid Build Coastguard Worker fa.bModifier = false;
380*3ac0a46fSAndroid Build Coastguard Worker fa.bShift = false;
381*3ac0a46fSAndroid Build Coastguard Worker fa.sValue = csValue;
382*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->DoActionFieldJavaScript(action, CPDF_AAction::kValidate,
383*3ac0a46fSAndroid Build Coastguard Worker pFormField, &fa);
384*3ac0a46fSAndroid Build Coastguard Worker return fa.bRC;
385*3ac0a46fSAndroid Build Coastguard Worker }
386*3ac0a46fSAndroid Build Coastguard Worker
DoAction_Hide(const CPDF_Action & action)387*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::DoAction_Hide(const CPDF_Action& action) {
388*3ac0a46fSAndroid Build Coastguard Worker DCHECK(action.GetDict());
389*3ac0a46fSAndroid Build Coastguard Worker std::vector<CPDF_FormField*> fields =
390*3ac0a46fSAndroid Build Coastguard Worker GetFieldFromObjects(action.GetAllFields());
391*3ac0a46fSAndroid Build Coastguard Worker bool bHide = action.GetHideStatus();
392*3ac0a46fSAndroid Build Coastguard Worker bool bChanged = false;
393*3ac0a46fSAndroid Build Coastguard Worker
394*3ac0a46fSAndroid Build Coastguard Worker for (CPDF_FormField* pField : fields) {
395*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
396*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormControl* pControl = pField->GetControl(i);
397*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pControl);
398*3ac0a46fSAndroid Build Coastguard Worker
399*3ac0a46fSAndroid Build Coastguard Worker if (CPDFSDK_Widget* pWidget = GetWidget(pControl)) {
400*3ac0a46fSAndroid Build Coastguard Worker uint32_t nFlags = pWidget->GetFlags();
401*3ac0a46fSAndroid Build Coastguard Worker nFlags &= ~pdfium::annotation_flags::kInvisible;
402*3ac0a46fSAndroid Build Coastguard Worker nFlags &= ~pdfium::annotation_flags::kNoView;
403*3ac0a46fSAndroid Build Coastguard Worker if (bHide)
404*3ac0a46fSAndroid Build Coastguard Worker nFlags |= pdfium::annotation_flags::kHidden;
405*3ac0a46fSAndroid Build Coastguard Worker else
406*3ac0a46fSAndroid Build Coastguard Worker nFlags &= ~pdfium::annotation_flags::kHidden;
407*3ac0a46fSAndroid Build Coastguard Worker pWidget->SetFlags(nFlags);
408*3ac0a46fSAndroid Build Coastguard Worker pWidget->GetPageView()->UpdateView(pWidget);
409*3ac0a46fSAndroid Build Coastguard Worker bChanged = true;
410*3ac0a46fSAndroid Build Coastguard Worker }
411*3ac0a46fSAndroid Build Coastguard Worker }
412*3ac0a46fSAndroid Build Coastguard Worker }
413*3ac0a46fSAndroid Build Coastguard Worker
414*3ac0a46fSAndroid Build Coastguard Worker return bChanged;
415*3ac0a46fSAndroid Build Coastguard Worker }
416*3ac0a46fSAndroid Build Coastguard Worker
DoAction_SubmitForm(const CPDF_Action & action)417*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::DoAction_SubmitForm(const CPDF_Action& action) {
418*3ac0a46fSAndroid Build Coastguard Worker WideString sDestination = action.GetFilePath();
419*3ac0a46fSAndroid Build Coastguard Worker if (sDestination.IsEmpty())
420*3ac0a46fSAndroid Build Coastguard Worker return false;
421*3ac0a46fSAndroid Build Coastguard Worker
422*3ac0a46fSAndroid Build Coastguard Worker if (action.HasFields()) {
423*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFlags = action.GetFlags();
424*3ac0a46fSAndroid Build Coastguard Worker std::vector<CPDF_FormField*> fields =
425*3ac0a46fSAndroid Build Coastguard Worker GetFieldFromObjects(action.GetAllFields());
426*3ac0a46fSAndroid Build Coastguard Worker if (!fields.empty()) {
427*3ac0a46fSAndroid Build Coastguard Worker bool bIncludeOrExclude = !(dwFlags & 0x01);
428*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInteractiveForm->CheckRequiredFields(&fields, bIncludeOrExclude))
429*3ac0a46fSAndroid Build Coastguard Worker return false;
430*3ac0a46fSAndroid Build Coastguard Worker
431*3ac0a46fSAndroid Build Coastguard Worker return SubmitFields(sDestination, fields, bIncludeOrExclude, false);
432*3ac0a46fSAndroid Build Coastguard Worker }
433*3ac0a46fSAndroid Build Coastguard Worker }
434*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInteractiveForm->CheckRequiredFields(nullptr, true))
435*3ac0a46fSAndroid Build Coastguard Worker return false;
436*3ac0a46fSAndroid Build Coastguard Worker
437*3ac0a46fSAndroid Build Coastguard Worker return SubmitForm(sDestination);
438*3ac0a46fSAndroid Build Coastguard Worker }
439*3ac0a46fSAndroid Build Coastguard Worker
SubmitFields(const WideString & csDestination,const std::vector<CPDF_FormField * > & fields,bool bIncludeOrExclude,bool bUrlEncoded)440*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::SubmitFields(
441*3ac0a46fSAndroid Build Coastguard Worker const WideString& csDestination,
442*3ac0a46fSAndroid Build Coastguard Worker const std::vector<CPDF_FormField*>& fields,
443*3ac0a46fSAndroid Build Coastguard Worker bool bIncludeOrExclude,
444*3ac0a46fSAndroid Build Coastguard Worker bool bUrlEncoded) {
445*3ac0a46fSAndroid Build Coastguard Worker ByteString text_buf = ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude);
446*3ac0a46fSAndroid Build Coastguard Worker if (text_buf.IsEmpty())
447*3ac0a46fSAndroid Build Coastguard Worker return false;
448*3ac0a46fSAndroid Build Coastguard Worker
449*3ac0a46fSAndroid Build Coastguard Worker if (bUrlEncoded) {
450*3ac0a46fSAndroid Build Coastguard Worker text_buf = FDFToURLEncodedData(text_buf);
451*3ac0a46fSAndroid Build Coastguard Worker if (text_buf.IsEmpty())
452*3ac0a46fSAndroid Build Coastguard Worker return false;
453*3ac0a46fSAndroid Build Coastguard Worker }
454*3ac0a46fSAndroid Build Coastguard Worker
455*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->SubmitForm(text_buf.raw_span(), csDestination);
456*3ac0a46fSAndroid Build Coastguard Worker return true;
457*3ac0a46fSAndroid Build Coastguard Worker }
458*3ac0a46fSAndroid Build Coastguard Worker
ExportFieldsToFDFTextBuf(const std::vector<CPDF_FormField * > & fields,bool bIncludeOrExclude)459*3ac0a46fSAndroid Build Coastguard Worker ByteString CPDFSDK_InteractiveForm::ExportFieldsToFDFTextBuf(
460*3ac0a46fSAndroid Build Coastguard Worker const std::vector<CPDF_FormField*>& fields,
461*3ac0a46fSAndroid Build Coastguard Worker bool bIncludeOrExclude) {
462*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFDF_Document> pFDF = m_pInteractiveForm->ExportToFDF(
463*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->GetFilePath(), fields, bIncludeOrExclude);
464*3ac0a46fSAndroid Build Coastguard Worker
465*3ac0a46fSAndroid Build Coastguard Worker return pFDF ? pFDF->WriteToString() : ByteString();
466*3ac0a46fSAndroid Build Coastguard Worker }
467*3ac0a46fSAndroid Build Coastguard Worker
SubmitForm(const WideString & sDestination)468*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::SubmitForm(const WideString& sDestination) {
469*3ac0a46fSAndroid Build Coastguard Worker if (sDestination.IsEmpty())
470*3ac0a46fSAndroid Build Coastguard Worker return false;
471*3ac0a46fSAndroid Build Coastguard Worker
472*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFDF_Document> pFDFDoc =
473*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->ExportToFDF(m_pFormFillEnv->GetFilePath());
474*3ac0a46fSAndroid Build Coastguard Worker if (!pFDFDoc)
475*3ac0a46fSAndroid Build Coastguard Worker return false;
476*3ac0a46fSAndroid Build Coastguard Worker
477*3ac0a46fSAndroid Build Coastguard Worker ByteString fdf_buffer = pFDFDoc->WriteToString();
478*3ac0a46fSAndroid Build Coastguard Worker if (fdf_buffer.IsEmpty())
479*3ac0a46fSAndroid Build Coastguard Worker return false;
480*3ac0a46fSAndroid Build Coastguard Worker
481*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->SubmitForm(fdf_buffer.raw_span(), sDestination);
482*3ac0a46fSAndroid Build Coastguard Worker return true;
483*3ac0a46fSAndroid Build Coastguard Worker }
484*3ac0a46fSAndroid Build Coastguard Worker
ExportFormToFDFTextBuf()485*3ac0a46fSAndroid Build Coastguard Worker ByteString CPDFSDK_InteractiveForm::ExportFormToFDFTextBuf() {
486*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFDF_Document> pFDF =
487*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->ExportToFDF(m_pFormFillEnv->GetFilePath());
488*3ac0a46fSAndroid Build Coastguard Worker
489*3ac0a46fSAndroid Build Coastguard Worker return pFDF ? pFDF->WriteToString() : ByteString();
490*3ac0a46fSAndroid Build Coastguard Worker }
491*3ac0a46fSAndroid Build Coastguard Worker
DoAction_ResetForm(const CPDF_Action & action)492*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::DoAction_ResetForm(const CPDF_Action& action) {
493*3ac0a46fSAndroid Build Coastguard Worker DCHECK(action.GetDict());
494*3ac0a46fSAndroid Build Coastguard Worker if (!action.HasFields()) {
495*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->ResetForm();
496*3ac0a46fSAndroid Build Coastguard Worker return;
497*3ac0a46fSAndroid Build Coastguard Worker }
498*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwFlags = action.GetFlags();
499*3ac0a46fSAndroid Build Coastguard Worker std::vector<CPDF_FormField*> fields =
500*3ac0a46fSAndroid Build Coastguard Worker GetFieldFromObjects(action.GetAllFields());
501*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->ResetForm(fields, !(dwFlags & 0x01));
502*3ac0a46fSAndroid Build Coastguard Worker }
503*3ac0a46fSAndroid Build Coastguard Worker
GetFieldFromObjects(const std::vector<RetainPtr<const CPDF_Object>> & objects) const504*3ac0a46fSAndroid Build Coastguard Worker std::vector<CPDF_FormField*> CPDFSDK_InteractiveForm::GetFieldFromObjects(
505*3ac0a46fSAndroid Build Coastguard Worker const std::vector<RetainPtr<const CPDF_Object>>& objects) const {
506*3ac0a46fSAndroid Build Coastguard Worker std::vector<CPDF_FormField*> fields;
507*3ac0a46fSAndroid Build Coastguard Worker for (const CPDF_Object* pObject : objects) {
508*3ac0a46fSAndroid Build Coastguard Worker if (!pObject || !pObject->IsString())
509*3ac0a46fSAndroid Build Coastguard Worker continue;
510*3ac0a46fSAndroid Build Coastguard Worker
511*3ac0a46fSAndroid Build Coastguard Worker WideString csName = pObject->GetUnicodeText();
512*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pField = m_pInteractiveForm->GetField(0, csName);
513*3ac0a46fSAndroid Build Coastguard Worker if (pField)
514*3ac0a46fSAndroid Build Coastguard Worker fields.push_back(pField);
515*3ac0a46fSAndroid Build Coastguard Worker }
516*3ac0a46fSAndroid Build Coastguard Worker return fields;
517*3ac0a46fSAndroid Build Coastguard Worker }
518*3ac0a46fSAndroid Build Coastguard Worker
BeforeValueChange(CPDF_FormField * pField,const WideString & csValue)519*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::BeforeValueChange(CPDF_FormField* pField,
520*3ac0a46fSAndroid Build Coastguard Worker const WideString& csValue) {
521*3ac0a46fSAndroid Build Coastguard Worker FormFieldType fieldType = pField->GetFieldType();
522*3ac0a46fSAndroid Build Coastguard Worker if (!IsFormFieldTypeComboOrText(fieldType))
523*3ac0a46fSAndroid Build Coastguard Worker return true;
524*3ac0a46fSAndroid Build Coastguard Worker if (!OnKeyStrokeCommit(pField, csValue))
525*3ac0a46fSAndroid Build Coastguard Worker return false;
526*3ac0a46fSAndroid Build Coastguard Worker return OnValidate(pField, csValue);
527*3ac0a46fSAndroid Build Coastguard Worker }
528*3ac0a46fSAndroid Build Coastguard Worker
AfterValueChange(CPDF_FormField * pField)529*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::AfterValueChange(CPDF_FormField* pField) {
530*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
531*3ac0a46fSAndroid Build Coastguard Worker SynchronizeField(pField);
532*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
533*3ac0a46fSAndroid Build Coastguard Worker
534*3ac0a46fSAndroid Build Coastguard Worker FormFieldType fieldType = pField->GetFieldType();
535*3ac0a46fSAndroid Build Coastguard Worker if (!IsFormFieldTypeComboOrText(fieldType))
536*3ac0a46fSAndroid Build Coastguard Worker return;
537*3ac0a46fSAndroid Build Coastguard Worker
538*3ac0a46fSAndroid Build Coastguard Worker OnCalculate(pField);
539*3ac0a46fSAndroid Build Coastguard Worker ResetFieldAppearance(pField, OnFormat(pField));
540*3ac0a46fSAndroid Build Coastguard Worker UpdateField(pField);
541*3ac0a46fSAndroid Build Coastguard Worker }
542*3ac0a46fSAndroid Build Coastguard Worker
BeforeSelectionChange(CPDF_FormField * pField,const WideString & csValue)543*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::BeforeSelectionChange(CPDF_FormField* pField,
544*3ac0a46fSAndroid Build Coastguard Worker const WideString& csValue) {
545*3ac0a46fSAndroid Build Coastguard Worker if (pField->GetFieldType() != FormFieldType::kListBox)
546*3ac0a46fSAndroid Build Coastguard Worker return true;
547*3ac0a46fSAndroid Build Coastguard Worker if (!OnKeyStrokeCommit(pField, csValue))
548*3ac0a46fSAndroid Build Coastguard Worker return false;
549*3ac0a46fSAndroid Build Coastguard Worker return OnValidate(pField, csValue);
550*3ac0a46fSAndroid Build Coastguard Worker }
551*3ac0a46fSAndroid Build Coastguard Worker
AfterSelectionChange(CPDF_FormField * pField)552*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::AfterSelectionChange(CPDF_FormField* pField) {
553*3ac0a46fSAndroid Build Coastguard Worker if (pField->GetFieldType() != FormFieldType::kListBox)
554*3ac0a46fSAndroid Build Coastguard Worker return;
555*3ac0a46fSAndroid Build Coastguard Worker
556*3ac0a46fSAndroid Build Coastguard Worker OnCalculate(pField);
557*3ac0a46fSAndroid Build Coastguard Worker ResetFieldAppearance(pField, absl::nullopt);
558*3ac0a46fSAndroid Build Coastguard Worker UpdateField(pField);
559*3ac0a46fSAndroid Build Coastguard Worker }
560*3ac0a46fSAndroid Build Coastguard Worker
AfterCheckedStatusChange(CPDF_FormField * pField)561*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::AfterCheckedStatusChange(CPDF_FormField* pField) {
562*3ac0a46fSAndroid Build Coastguard Worker FormFieldType fieldType = pField->GetFieldType();
563*3ac0a46fSAndroid Build Coastguard Worker if (fieldType != FormFieldType::kCheckBox &&
564*3ac0a46fSAndroid Build Coastguard Worker fieldType != FormFieldType::kRadioButton)
565*3ac0a46fSAndroid Build Coastguard Worker return;
566*3ac0a46fSAndroid Build Coastguard Worker
567*3ac0a46fSAndroid Build Coastguard Worker OnCalculate(pField);
568*3ac0a46fSAndroid Build Coastguard Worker UpdateField(pField);
569*3ac0a46fSAndroid Build Coastguard Worker }
570*3ac0a46fSAndroid Build Coastguard Worker
AfterFormReset(CPDF_InteractiveForm * pForm)571*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::AfterFormReset(CPDF_InteractiveForm* pForm) {
572*3ac0a46fSAndroid Build Coastguard Worker OnCalculate(nullptr);
573*3ac0a46fSAndroid Build Coastguard Worker }
574*3ac0a46fSAndroid Build Coastguard Worker
IsNeedHighLight(FormFieldType fieldType) const575*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_InteractiveForm::IsNeedHighLight(FormFieldType fieldType) const {
576*3ac0a46fSAndroid Build Coastguard Worker if (fieldType == FormFieldType::kUnknown)
577*3ac0a46fSAndroid Build Coastguard Worker return false;
578*3ac0a46fSAndroid Build Coastguard Worker
579*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
580*3ac0a46fSAndroid Build Coastguard Worker // For the XFA fields, we need to return if the specific field type has
581*3ac0a46fSAndroid Build Coastguard Worker // highlight enabled or if the general XFA field type has it enabled.
582*3ac0a46fSAndroid Build Coastguard Worker if (IsFormFieldTypeXFA(fieldType)) {
583*3ac0a46fSAndroid Build Coastguard Worker if (!m_NeedsHighlight[static_cast<size_t>(fieldType)])
584*3ac0a46fSAndroid Build Coastguard Worker return m_NeedsHighlight[static_cast<size_t>(FormFieldType::kXFA)];
585*3ac0a46fSAndroid Build Coastguard Worker }
586*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
587*3ac0a46fSAndroid Build Coastguard Worker return m_NeedsHighlight[static_cast<size_t>(fieldType)];
588*3ac0a46fSAndroid Build Coastguard Worker }
589*3ac0a46fSAndroid Build Coastguard Worker
RemoveAllHighLights()590*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::RemoveAllHighLights() {
591*3ac0a46fSAndroid Build Coastguard Worker std::fill(std::begin(m_HighlightColor), std::end(m_HighlightColor),
592*3ac0a46fSAndroid Build Coastguard Worker kWhiteBGR);
593*3ac0a46fSAndroid Build Coastguard Worker std::fill(std::begin(m_NeedsHighlight), std::end(m_NeedsHighlight), false);
594*3ac0a46fSAndroid Build Coastguard Worker }
595*3ac0a46fSAndroid Build Coastguard Worker
SetHighlightColor(FX_COLORREF clr,FormFieldType fieldType)596*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::SetHighlightColor(FX_COLORREF clr,
597*3ac0a46fSAndroid Build Coastguard Worker FormFieldType fieldType) {
598*3ac0a46fSAndroid Build Coastguard Worker if (fieldType == FormFieldType::kUnknown)
599*3ac0a46fSAndroid Build Coastguard Worker return;
600*3ac0a46fSAndroid Build Coastguard Worker
601*3ac0a46fSAndroid Build Coastguard Worker m_HighlightColor[static_cast<size_t>(fieldType)] = clr;
602*3ac0a46fSAndroid Build Coastguard Worker m_NeedsHighlight[static_cast<size_t>(fieldType)] = true;
603*3ac0a46fSAndroid Build Coastguard Worker }
604*3ac0a46fSAndroid Build Coastguard Worker
SetAllHighlightColors(FX_COLORREF clr)605*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_InteractiveForm::SetAllHighlightColors(FX_COLORREF clr) {
606*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0; i < kFormFieldTypeCount; ++i) {
607*3ac0a46fSAndroid Build Coastguard Worker m_HighlightColor[i] = clr;
608*3ac0a46fSAndroid Build Coastguard Worker m_NeedsHighlight[i] = true;
609*3ac0a46fSAndroid Build Coastguard Worker }
610*3ac0a46fSAndroid Build Coastguard Worker }
611*3ac0a46fSAndroid Build Coastguard Worker
GetHighlightColor(FormFieldType fieldType)612*3ac0a46fSAndroid Build Coastguard Worker FX_COLORREF CPDFSDK_InteractiveForm::GetHighlightColor(
613*3ac0a46fSAndroid Build Coastguard Worker FormFieldType fieldType) {
614*3ac0a46fSAndroid Build Coastguard Worker if (fieldType == FormFieldType::kUnknown)
615*3ac0a46fSAndroid Build Coastguard Worker return kWhiteBGR;
616*3ac0a46fSAndroid Build Coastguard Worker
617*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
618*3ac0a46fSAndroid Build Coastguard Worker // For the XFA fields, we need to return the specific field type highlight
619*3ac0a46fSAndroid Build Coastguard Worker // colour or the general XFA field type colour if present.
620*3ac0a46fSAndroid Build Coastguard Worker if (IsFormFieldTypeXFA(fieldType)) {
621*3ac0a46fSAndroid Build Coastguard Worker if (!m_NeedsHighlight[static_cast<size_t>(fieldType)] &&
622*3ac0a46fSAndroid Build Coastguard Worker m_NeedsHighlight[static_cast<size_t>(FormFieldType::kXFA)]) {
623*3ac0a46fSAndroid Build Coastguard Worker return m_HighlightColor[static_cast<size_t>(FormFieldType::kXFA)];
624*3ac0a46fSAndroid Build Coastguard Worker }
625*3ac0a46fSAndroid Build Coastguard Worker }
626*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
627*3ac0a46fSAndroid Build Coastguard Worker return m_HighlightColor[static_cast<size_t>(fieldType)];
628*3ac0a46fSAndroid Build Coastguard Worker }
629