blob: 7ecaeac31071706734db11df368af1b37c5989a0 [file] [log] [blame]
jaepark611adb82016-08-17 11:34:36 -07001// Copyright 2016 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
dsinclair114e46a2016-09-29 17:18:21 -07007#include "fpdfsdk/cpdfsdk_interform.h"
jaepark611adb82016-08-17 11:34:36 -07008
9#include <algorithm>
10#include <memory>
thestig7c292e02016-09-28 14:14:26 -070011#include <vector>
jaepark611adb82016-08-17 11:34:36 -070012
dsinclair8a752ab2016-09-29 11:59:54 -070013#include "core/fpdfapi/fpdf_page/cpdf_page.h"
dsinclairc6c425a2016-09-29 12:01:30 -070014#include "core/fpdfapi/fpdf_parser/cfdf_document.h"
15#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
16#include "core/fpdfapi/fpdf_parser/cpdf_document.h"
17#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
dsinclair1727aee2016-09-29 13:12:56 -070018#include "core/fpdfdoc/cpdf_actionfields.h"
19#include "core/fpdfdoc/cpdf_interform.h"
dsinclair74a34fc2016-09-29 16:41:42 -070020#include "core/fxge/cfx_graphstatedata.h"
21#include "core/fxge/cfx_pathdata.h"
22#include "core/fxge/cfx_renderdevice.h"
dsinclair114e46a2016-09-29 17:18:21 -070023#include "fpdfsdk/cba_annotiterator.h"
24#include "fpdfsdk/cpdfsdk_annot.h"
25#include "fpdfsdk/cpdfsdk_document.h"
26#include "fpdfsdk/cpdfsdk_environment.h"
27#include "fpdfsdk/cpdfsdk_pageview.h"
28#include "fpdfsdk/cpdfsdk_widget.h"
jaepark611adb82016-08-17 11:34:36 -070029#include "fpdfsdk/formfiller/cffl_formfiller.h"
dsinclair114e46a2016-09-29 17:18:21 -070030#include "fpdfsdk/fsdk_actionhandler.h"
31#include "fpdfsdk/fsdk_define.h"
dsinclair0bb385b2016-09-29 17:03:59 -070032#include "fpdfsdk/fxedit/fxet_edit.h"
dsinclair114e46a2016-09-29 17:18:21 -070033#include "fpdfsdk/ipdfsdk_annothandler.h"
jaepark611adb82016-08-17 11:34:36 -070034#include "fpdfsdk/javascript/ijs_context.h"
35#include "fpdfsdk/javascript/ijs_runtime.h"
36#include "fpdfsdk/pdfwindow/PWL_Utils.h"
37#include "third_party/base/stl_util.h"
38
39#ifdef PDF_ENABLE_XFA
dsinclair114e46a2016-09-29 17:18:21 -070040#include "fpdfsdk/cpdfsdk_xfawidget.h"
dsinclairbec76922016-09-29 16:52:30 -070041#include "fpdfsdk/fpdfxfa/fpdfxfa_doc.h"
42#include "fpdfsdk/fpdfxfa/fpdfxfa_util.h"
jaepark611adb82016-08-17 11:34:36 -070043#include "xfa/fxfa/include/cxfa_eventparam.h"
44#include "xfa/fxfa/include/xfa_ffdocview.h"
45#include "xfa/fxfa/include/xfa_ffwidget.h"
46#include "xfa/fxfa/include/xfa_ffwidgethandler.h"
47#endif // PDF_ENABLE_XFA
48
49CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
50 : m_pDocument(pDocument),
51 m_pInterForm(new CPDF_InterForm(m_pDocument->GetPDFDocument())),
52#ifdef PDF_ENABLE_XFA
53 m_bXfaCalculate(TRUE),
54 m_bXfaValidationsEnabled(TRUE),
55#endif // PDF_ENABLE_XFA
56 m_bCalculate(TRUE),
57 m_bBusy(FALSE),
58 m_iHighlightAlpha(0) {
59 m_pInterForm->SetFormNotify(this);
60 for (int i = 0; i < kNumFieldTypes; ++i)
61 m_bNeedHightlight[i] = FALSE;
62}
63
64CPDFSDK_InterForm::~CPDFSDK_InterForm() {
65 m_Map.clear();
66#ifdef PDF_ENABLE_XFA
67 m_XFAMap.clear();
68#endif // PDF_ENABLE_XFA
69}
70
71FX_BOOL CPDFSDK_InterForm::HighlightWidgets() {
72 return FALSE;
73}
74
75CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget,
76 FX_BOOL bNext) const {
jaepark956553e2016-08-31 06:49:27 -070077 std::unique_ptr<CBA_AnnotIterator> pIterator(new CBA_AnnotIterator(
78 pWidget->GetPageView(), CPDF_Annot::Subtype::WIDGET));
jaepark611adb82016-08-17 11:34:36 -070079
80 if (bNext)
81 return static_cast<CPDFSDK_Widget*>(pIterator->GetNextAnnot(pWidget));
82
83 return static_cast<CPDFSDK_Widget*>(pIterator->GetPrevAnnot(pWidget));
84}
85
86CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl,
87 bool createIfNeeded) const {
88 if (!pControl || !m_pInterForm)
89 return nullptr;
90
91 CPDFSDK_Widget* pWidget = nullptr;
92 const auto it = m_Map.find(pControl);
93 if (it != m_Map.end())
94 pWidget = it->second;
95 if (pWidget)
96 return pWidget;
97 if (!createIfNeeded)
98 return nullptr;
99
100 CPDF_Dictionary* pControlDict = pControl->GetWidget();
101 CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
102 CPDFSDK_PageView* pPage = nullptr;
103
dsinclair38fd8442016-09-15 10:15:32 -0700104 if (CPDF_Dictionary* pPageDict = pControlDict->GetDictFor("P")) {
jaepark611adb82016-08-17 11:34:36 -0700105 int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
106 if (nPageIndex >= 0)
107 pPage = m_pDocument->GetPageView(nPageIndex);
108 }
109
110 if (!pPage) {
111 int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
112 if (nPageIndex >= 0)
113 pPage = m_pDocument->GetPageView(nPageIndex);
114 }
115
116 if (!pPage)
117 return nullptr;
118
119 return static_cast<CPDFSDK_Widget*>(pPage->GetAnnotByDict(pControlDict));
120}
121
122void CPDFSDK_InterForm::GetWidgets(
123 const CFX_WideString& sFieldName,
124 std::vector<CPDFSDK_Widget*>* widgets) const {
125 for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) {
126 CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
127 ASSERT(pFormField);
128 GetWidgets(pFormField, widgets);
129 }
130}
131
132void CPDFSDK_InterForm::GetWidgets(
133 CPDF_FormField* pField,
134 std::vector<CPDFSDK_Widget*>* widgets) const {
135 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
136 CPDF_FormControl* pFormCtrl = pField->GetControl(i);
137 ASSERT(pFormCtrl);
138 CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, true);
139 if (pWidget)
140 widgets->push_back(pWidget);
141 }
142}
143
144int CPDFSDK_InterForm::GetPageIndexByAnnotDict(
145 CPDF_Document* pDocument,
146 CPDF_Dictionary* pAnnotDict) const {
147 ASSERT(pAnnotDict);
148
149 for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
150 if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) {
dsinclair38fd8442016-09-15 10:15:32 -0700151 if (CPDF_Array* pAnnots = pPageDict->GetArrayFor("Annots")) {
jaepark611adb82016-08-17 11:34:36 -0700152 for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) {
153 CPDF_Object* pDict = pAnnots->GetDirectObjectAt(j);
154 if (pAnnotDict == pDict)
155 return i;
156 }
157 }
158 }
159 }
160
161 return -1;
162}
163
164void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl,
165 CPDFSDK_Widget* pWidget) {
166 m_Map[pControl] = pWidget;
167}
168
169void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) {
170 m_Map.erase(pControl);
171}
172
173void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) {
174 m_bCalculate = bEnabled;
175}
176
177FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const {
178 return m_bCalculate;
179}
180
181#ifdef PDF_ENABLE_XFA
182void CPDFSDK_InterForm::AddXFAMap(CXFA_FFWidget* hWidget,
183 CPDFSDK_XFAWidget* pWidget) {
184 ASSERT(hWidget);
185 m_XFAMap[hWidget] = pWidget;
186}
187
188void CPDFSDK_InterForm::RemoveXFAMap(CXFA_FFWidget* hWidget) {
189 ASSERT(hWidget);
190 m_XFAMap.erase(hWidget);
191}
192
193CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(CXFA_FFWidget* hWidget) {
194 ASSERT(hWidget);
195 auto it = m_XFAMap.find(hWidget);
196 return it != m_XFAMap.end() ? it->second : nullptr;
197}
198
199void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) {
200 m_bXfaCalculate = bEnabled;
201}
202FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const {
203 return m_bXfaCalculate;
204}
205
206FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() {
207 return m_bXfaValidationsEnabled;
208}
209void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) {
210 m_bXfaValidationsEnabled = bEnabled;
211}
212
213void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField,
214 FX_BOOL bSynchronizeElse) {
215 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
216 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
217 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false))
218 pWidget->Synchronize(bSynchronizeElse);
219 }
220}
221#endif // PDF_ENABLE_XFA
222
223void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) {
dsinclair79db6092016-09-14 07:27:21 -0700224 CPDFSDK_Environment* pEnv = m_pDocument->GetEnv();
jaepark611adb82016-08-17 11:34:36 -0700225 ASSERT(pEnv);
226 if (!pEnv->IsJSInitiated())
227 return;
228
229 if (m_bBusy)
230 return;
231
232 m_bBusy = TRUE;
233
234 if (!IsCalculateEnabled()) {
235 m_bBusy = FALSE;
236 return;
237 }
238
239 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
240 pRuntime->SetReaderDocument(m_pDocument);
241
242 int nSize = m_pInterForm->CountFieldsInCalculationOrder();
243 for (int i = 0; i < nSize; i++) {
244 CPDF_FormField* pField = m_pInterForm->GetFieldInCalculationOrder(i);
245 if (!pField)
246 continue;
247
248 int nType = pField->GetFieldType();
249 if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
250 continue;
251
252 CPDF_AAction aAction = pField->GetAdditionalAction();
253 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Calculate))
254 continue;
255
256 CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
257 if (!action.GetDict())
258 continue;
259
260 CFX_WideString csJS = action.GetJavaScript();
261 if (csJS.IsEmpty())
262 continue;
263
264 IJS_Context* pContext = pRuntime->NewContext();
265 CFX_WideString sOldValue = pField->GetValue();
266 CFX_WideString sValue = sOldValue;
267 FX_BOOL bRC = TRUE;
268 pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
269
270 CFX_WideString sInfo;
271 FX_BOOL bRet = pContext->RunScript(csJS, &sInfo);
272 pRuntime->ReleaseContext(pContext);
273
274 if (bRet && bRC && sValue.Compare(sOldValue) != 0)
275 pField->SetValue(sValue, TRUE);
276 }
277
278 m_bBusy = FALSE;
279}
280
281CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField,
tsepez8c2a8cd2016-09-07 15:29:11 -0700282 FX_BOOL& bFormatted) {
jaepark611adb82016-08-17 11:34:36 -0700283 CFX_WideString sValue = pFormField->GetValue();
dsinclair79db6092016-09-14 07:27:21 -0700284 CPDFSDK_Environment* pEnv = m_pDocument->GetEnv();
jaepark611adb82016-08-17 11:34:36 -0700285 ASSERT(pEnv);
286 if (!pEnv->IsJSInitiated()) {
tsepez8c2a8cd2016-09-07 15:29:11 -0700287 bFormatted = FALSE;
jaepark611adb82016-08-17 11:34:36 -0700288 return sValue;
289 }
290
291 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
292 pRuntime->SetReaderDocument(m_pDocument);
293
294 if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX &&
295 pFormField->CountSelectedItems() > 0) {
296 int index = pFormField->GetSelectedIndex(0);
297 if (index >= 0)
298 sValue = pFormField->GetOptionLabel(index);
299 }
300
tsepez8c2a8cd2016-09-07 15:29:11 -0700301 bFormatted = FALSE;
jaepark611adb82016-08-17 11:34:36 -0700302
303 CPDF_AAction aAction = pFormField->GetAdditionalAction();
304 if (aAction.GetDict() && aAction.ActionExist(CPDF_AAction::Format)) {
305 CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
306 if (action.GetDict()) {
307 CFX_WideString script = action.GetJavaScript();
308 if (!script.IsEmpty()) {
309 CFX_WideString Value = sValue;
310
311 IJS_Context* pContext = pRuntime->NewContext();
312 pContext->OnField_Format(pFormField, Value, TRUE);
313 CFX_WideString sInfo;
314 FX_BOOL bRet = pContext->RunScript(script, &sInfo);
315 pRuntime->ReleaseContext(pContext);
316
317 if (bRet) {
318 sValue = Value;
tsepez8c2a8cd2016-09-07 15:29:11 -0700319 bFormatted = TRUE;
jaepark611adb82016-08-17 11:34:36 -0700320 }
321 }
322 }
323 }
324
325 return sValue;
326}
327
328void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField,
tsepeza31da742016-09-08 11:28:14 -0700329 const CFX_WideString* sValue,
jaepark611adb82016-08-17 11:34:36 -0700330 FX_BOOL bValueChanged) {
331 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
332 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
333 ASSERT(pFormCtrl);
334 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false))
335 pWidget->ResetAppearance(sValue, bValueChanged);
336 }
337}
338
339void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) {
340 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
341 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
342 ASSERT(pFormCtrl);
343
344 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) {
dsinclair79db6092016-09-14 07:27:21 -0700345 CPDFSDK_Environment* pEnv = m_pDocument->GetEnv();
jaepark611adb82016-08-17 11:34:36 -0700346 UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
347 CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, false);
dsinclairb94d7c92016-09-21 12:07:00 -0700348 FX_RECT rcBBox =
349 pEnv->GetInteractiveFormFiller()->GetViewBBox(pPageView, pWidget);
jaepark611adb82016-08-17 11:34:36 -0700350
dsinclair1f248902016-09-14 10:38:17 -0700351 pEnv->Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right,
352 rcBBox.bottom);
jaepark611adb82016-08-17 11:34:36 -0700353 }
354 }
355}
356
357FX_BOOL CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
358 const CFX_WideString& csValue) {
359 CPDF_AAction aAction = pFormField->GetAdditionalAction();
360 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::KeyStroke))
361 return TRUE;
362
363 CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
364 if (!action.GetDict())
365 return TRUE;
366
dsinclair79db6092016-09-14 07:27:21 -0700367 CPDFSDK_Environment* pEnv = m_pDocument->GetEnv();
jaepark611adb82016-08-17 11:34:36 -0700368 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
369 PDFSDK_FieldAction fa;
dsinclair1f248902016-09-14 10:38:17 -0700370 fa.bModifier = pEnv->IsCTRLKeyDown(0);
371 fa.bShift = pEnv->IsSHIFTKeyDown(0);
jaepark611adb82016-08-17 11:34:36 -0700372 fa.sValue = csValue;
373 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
374 m_pDocument, pFormField, fa);
375 return fa.bRC;
376}
377
378FX_BOOL CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField,
379 const CFX_WideString& csValue) {
380 CPDF_AAction aAction = pFormField->GetAdditionalAction();
381 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Validate))
382 return TRUE;
383
384 CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
385 if (!action.GetDict())
386 return TRUE;
387
dsinclair79db6092016-09-14 07:27:21 -0700388 CPDFSDK_Environment* pEnv = m_pDocument->GetEnv();
jaepark611adb82016-08-17 11:34:36 -0700389 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
390 PDFSDK_FieldAction fa;
dsinclair1f248902016-09-14 10:38:17 -0700391 fa.bModifier = pEnv->IsCTRLKeyDown(0);
392 fa.bShift = pEnv->IsSHIFTKeyDown(0);
jaepark611adb82016-08-17 11:34:36 -0700393 fa.sValue = csValue;
394 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate,
395 m_pDocument, pFormField, fa);
396 return fa.bRC;
397}
398
399FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) {
400 ASSERT(action.GetDict());
401
402 CPDF_ActionFields af(&action);
403 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
404 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
405
406 bool bHide = action.GetHideStatus();
407 FX_BOOL bChanged = FALSE;
408
409 for (CPDF_FormField* pField : fields) {
410 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
411 CPDF_FormControl* pControl = pField->GetControl(i);
412 ASSERT(pControl);
413
414 if (CPDFSDK_Widget* pWidget = GetWidget(pControl, false)) {
415 uint32_t nFlags = pWidget->GetFlags();
416 nFlags &= ~ANNOTFLAG_INVISIBLE;
417 nFlags &= ~ANNOTFLAG_NOVIEW;
418 if (bHide)
419 nFlags |= ANNOTFLAG_HIDDEN;
420 else
421 nFlags &= ~ANNOTFLAG_HIDDEN;
422 pWidget->SetFlags(nFlags);
423 pWidget->GetPageView()->UpdateView(pWidget);
424 bChanged = TRUE;
425 }
426 }
427 }
428
429 return bChanged;
430}
431
432FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) {
433 CFX_WideString sDestination = action.GetFilePath();
434 if (sDestination.IsEmpty())
435 return FALSE;
436
437 CPDF_Dictionary* pActionDict = action.GetDict();
438 if (pActionDict->KeyExist("Fields")) {
439 CPDF_ActionFields af(&action);
440 uint32_t dwFlags = action.GetFlags();
441 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
442 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
443 if (!fields.empty()) {
444 bool bIncludeOrExclude = !(dwFlags & 0x01);
445 if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
446 return FALSE;
447
448 return SubmitFields(sDestination, fields, bIncludeOrExclude, false);
449 }
450 }
451 if (m_pInterForm->CheckRequiredFields(nullptr, true))
452 return FALSE;
453
454 return SubmitForm(sDestination, FALSE);
455}
456
457FX_BOOL CPDFSDK_InterForm::SubmitFields(
458 const CFX_WideString& csDestination,
459 const std::vector<CPDF_FormField*>& fields,
460 bool bIncludeOrExclude,
461 bool bUrlEncoded) {
dsinclair79db6092016-09-14 07:27:21 -0700462 CPDFSDK_Environment* pEnv = m_pDocument->GetEnv();
jaepark611adb82016-08-17 11:34:36 -0700463
464 CFX_ByteTextBuf textBuf;
465 ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
466
467 uint8_t* pBuffer = textBuf.GetBuffer();
468 FX_STRSIZE nBufSize = textBuf.GetLength();
469
470 if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
471 return FALSE;
472
473 pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
474 return TRUE;
475}
476
477FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile,
478 CFX_WideString csTxtFile) {
479 return TRUE;
480}
481
482FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf,
483 FX_STRSIZE& nBufSize) {
484 CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
485 if (!pFDF)
486 return TRUE;
487
dsinclair38fd8442016-09-15 10:15:32 -0700488 CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictFor("FDF");
jaepark611adb82016-08-17 11:34:36 -0700489 if (!pMainDict)
490 return FALSE;
491
dsinclair38fd8442016-09-15 10:15:32 -0700492 CPDF_Array* pFields = pMainDict->GetArrayFor("Fields");
jaepark611adb82016-08-17 11:34:36 -0700493 if (!pFields)
494 return FALSE;
495
496 CFX_ByteTextBuf fdfEncodedData;
497 for (uint32_t i = 0; i < pFields->GetCount(); i++) {
498 CPDF_Dictionary* pField = pFields->GetDictAt(i);
499 if (!pField)
500 continue;
501 CFX_WideString name;
dsinclair38fd8442016-09-15 10:15:32 -0700502 name = pField->GetUnicodeTextFor("T");
jaepark611adb82016-08-17 11:34:36 -0700503 CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
dsinclair38fd8442016-09-15 10:15:32 -0700504 CFX_ByteString csBValue = pField->GetStringFor("V");
jaepark611adb82016-08-17 11:34:36 -0700505 CFX_WideString csWValue = PDF_DecodeText(csBValue);
506 CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
507
508 fdfEncodedData << name_b.GetBuffer(name_b.GetLength());
509 name_b.ReleaseBuffer();
510 fdfEncodedData << "=";
511 fdfEncodedData << csValue_b.GetBuffer(csValue_b.GetLength());
512 csValue_b.ReleaseBuffer();
513 if (i != pFields->GetCount() - 1)
514 fdfEncodedData << "&";
515 }
516
517 nBufSize = fdfEncodedData.GetLength();
518 pBuf = FX_Alloc(uint8_t, nBufSize);
519 FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
520 return TRUE;
521}
522
523FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(
524 const std::vector<CPDF_FormField*>& fields,
525 bool bIncludeOrExclude,
526 CFX_ByteTextBuf& textBuf) {
527 std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF(
thestig7c292e02016-09-28 14:14:26 -0700528 m_pDocument->GetPath().AsStringC(), fields, bIncludeOrExclude, false));
jaepark611adb82016-08-17 11:34:36 -0700529 return pFDF ? pFDF->WriteBuf(textBuf) : FALSE;
530}
531
532CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(
533 const CFX_WideString& sFileExt) {
534 return L"";
535}
536
537FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination,
538 FX_BOOL bUrlEncoded) {
539 if (sDestination.IsEmpty())
540 return FALSE;
541
542 if (!m_pDocument || !m_pInterForm)
543 return FALSE;
544
dsinclair79db6092016-09-14 07:27:21 -0700545 CPDFSDK_Environment* pEnv = m_pDocument->GetEnv();
jaepark611adb82016-08-17 11:34:36 -0700546 CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
thestig7c292e02016-09-28 14:14:26 -0700547 CFDF_Document* pFDFDoc =
548 m_pInterForm->ExportToFDF(wsPDFFilePath.AsStringC(), false);
jaepark611adb82016-08-17 11:34:36 -0700549 if (!pFDFDoc)
550 return FALSE;
551
552 CFX_ByteTextBuf FdfBuffer;
553 FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
554 delete pFDFDoc;
555 if (!bRet)
556 return FALSE;
557
558 uint8_t* pBuffer = FdfBuffer.GetBuffer();
559 FX_STRSIZE nBufSize = FdfBuffer.GetLength();
560
561 if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
562 return FALSE;
563
564 pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
565
566 if (bUrlEncoded)
567 FX_Free(pBuffer);
568
569 return TRUE;
570}
571
572FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
573 CFDF_Document* pFDF =
thestig7c292e02016-09-28 14:14:26 -0700574 m_pInterForm->ExportToFDF(m_pDocument->GetPath().AsStringC(), false);
jaepark611adb82016-08-17 11:34:36 -0700575 if (!pFDF)
576 return FALSE;
577
578 FX_BOOL bRet = pFDF->WriteBuf(textBuf);
579 delete pFDF;
580
581 return bRet;
582}
583
584FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) {
585 ASSERT(action.GetDict());
586
587 CPDF_Dictionary* pActionDict = action.GetDict();
588 if (!pActionDict->KeyExist("Fields"))
589 return m_pInterForm->ResetForm(true);
590
591 CPDF_ActionFields af(&action);
592 uint32_t dwFlags = action.GetFlags();
593
594 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
595 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
596 return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true);
597}
598
599FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) {
600 return FALSE;
601}
602
603std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects(
604 const std::vector<CPDF_Object*>& objects) const {
605 std::vector<CPDF_FormField*> fields;
606 for (CPDF_Object* pObject : objects) {
607 if (pObject && pObject->IsString()) {
608 CFX_WideString csName = pObject->GetUnicodeText();
609 CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
610 if (pField)
611 fields.push_back(pField);
612 }
613 }
614 return fields;
615}
616
617int CPDFSDK_InterForm::BeforeValueChange(CPDF_FormField* pField,
618 const CFX_WideString& csValue) {
619 int nType = pField->GetFieldType();
620 if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
621 return 0;
622
623 if (!OnKeyStrokeCommit(pField, csValue))
624 return -1;
625
626 if (!OnValidate(pField, csValue))
627 return -1;
628
629 return 1;
630}
631
632void CPDFSDK_InterForm::AfterValueChange(CPDF_FormField* pField) {
633#ifdef PDF_ENABLE_XFA
634 SynchronizeField(pField, FALSE);
635#endif // PDF_ENABLE_XFA
636 int nType = pField->GetFieldType();
637 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
638 OnCalculate(pField);
tsepez8c2a8cd2016-09-07 15:29:11 -0700639 FX_BOOL bFormatted = FALSE;
640 CFX_WideString sValue = OnFormat(pField, bFormatted);
tsepeza31da742016-09-08 11:28:14 -0700641 ResetFieldAppearance(pField, bFormatted ? &sValue : nullptr, TRUE);
jaepark611adb82016-08-17 11:34:36 -0700642 UpdateField(pField);
643 }
644}
645
646int CPDFSDK_InterForm::BeforeSelectionChange(CPDF_FormField* pField,
647 const CFX_WideString& csValue) {
648 if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
649 return 0;
650
651 if (!OnKeyStrokeCommit(pField, csValue))
652 return -1;
653
654 if (!OnValidate(pField, csValue))
655 return -1;
656
657 return 1;
658}
659
660void CPDFSDK_InterForm::AfterSelectionChange(CPDF_FormField* pField) {
661 if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
662 return;
663
664 OnCalculate(pField);
665 ResetFieldAppearance(pField, nullptr, TRUE);
666 UpdateField(pField);
667}
668
669void CPDFSDK_InterForm::AfterCheckedStatusChange(CPDF_FormField* pField) {
670 int nType = pField->GetFieldType();
671 if (nType != FIELDTYPE_CHECKBOX && nType != FIELDTYPE_RADIOBUTTON)
672 return;
673
674 OnCalculate(pField);
675 UpdateField(pField);
676}
677
678int CPDFSDK_InterForm::BeforeFormReset(CPDF_InterForm* pForm) {
679 return 0;
680}
681
682void CPDFSDK_InterForm::AfterFormReset(CPDF_InterForm* pForm) {
683 OnCalculate(nullptr);
684}
685
686int CPDFSDK_InterForm::BeforeFormImportData(CPDF_InterForm* pForm) {
687 return 0;
688}
689
690void CPDFSDK_InterForm::AfterFormImportData(CPDF_InterForm* pForm) {
691 OnCalculate(nullptr);
692}
693
694FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) {
695 if (nFieldType < 1 || nFieldType > kNumFieldTypes)
696 return FALSE;
697 return m_bNeedHightlight[nFieldType - 1];
698}
699
700void CPDFSDK_InterForm::RemoveAllHighLight() {
701 for (int i = 0; i < kNumFieldTypes; ++i)
702 m_bNeedHightlight[i] = FALSE;
703}
704
705void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) {
706 if (nFieldType < 0 || nFieldType > kNumFieldTypes)
707 return;
708 switch (nFieldType) {
709 case 0: {
710 for (int i = 0; i < kNumFieldTypes; ++i) {
711 m_aHighlightColor[i] = clr;
712 m_bNeedHightlight[i] = TRUE;
713 }
714 break;
715 }
716 default: {
717 m_aHighlightColor[nFieldType - 1] = clr;
718 m_bNeedHightlight[nFieldType - 1] = TRUE;
719 break;
720 }
721 }
722}
723
724FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) {
725 if (nFieldType < 0 || nFieldType > kNumFieldTypes)
726 return FXSYS_RGB(255, 255, 255);
727 if (nFieldType == 0)
728 return m_aHighlightColor[0];
729 return m_aHighlightColor[nFieldType - 1];
730}