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