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/fpdfxfa/cpdfxfa_docenvironment.h" 8 9 #include <memory> 10 11 #include "core/fpdfapi/parser/cpdf_array.h" 12 #include "core/fpdfapi/parser/cpdf_stream_acc.h" 13 #include "core/fpdfapi/parser/cpdf_string.h" 14 #include "core/fxcrt/cfx_retain_ptr.h" 15 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" 16 #include "fpdfsdk/cpdfsdk_interform.h" 17 #include "fpdfsdk/cpdfsdk_pageview.h" 18 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h" 19 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h" 20 #include "fpdfsdk/javascript/ijs_runtime.h" 21 #include "xfa/fxfa/xfa_ffdocview.h" 22 #include "xfa/fxfa/xfa_ffwidget.h" 23 #include "xfa/fxfa/xfa_ffwidgethandler.h" 24 25 #define IDS_XFA_Validate_Input \ 26 "At least one required field was empty. Please fill in the required " \ 27 "fields\r\n(highlighted) before continuing." 28 29 // submit 30 #define FXFA_CONFIG 0x00000001 31 #define FXFA_TEMPLATE 0x00000010 32 #define FXFA_LOCALESET 0x00000100 33 #define FXFA_DATASETS 0x00001000 34 #define FXFA_XMPMETA 0x00010000 35 #define FXFA_XFDF 0x00100000 36 #define FXFA_FORM 0x01000000 37 #define FXFA_PDF 0x10000000 38 #define FXFA_XFA_ALL 0x01111111 39 40 CPDFXFA_DocEnvironment::CPDFXFA_DocEnvironment(CPDFXFA_Context* pContext) 41 : m_pContext(pContext), m_pJSEventContext(nullptr) { 42 ASSERT(m_pContext); 43 } 44 45 CPDFXFA_DocEnvironment::~CPDFXFA_DocEnvironment() { 46 if (m_pJSEventContext && m_pContext->GetFormFillEnv()) { 47 m_pContext->GetFormFillEnv()->GetJSRuntime()->ReleaseEventContext( 48 m_pJSEventContext); 49 } 50 } 51 52 void CPDFXFA_DocEnvironment::SetChangeMark(CXFA_FFDoc* hDoc) { 53 if (hDoc == m_pContext->GetXFADoc() && m_pContext->GetFormFillEnv()) 54 m_pContext->GetFormFillEnv()->SetChangeMark(); 55 } 56 57 void CPDFXFA_DocEnvironment::InvalidateRect(CXFA_FFPageView* pPageView, 58 const CFX_RectF& rt, 59 uint32_t dwFlags /* = 0 */) { 60 if (!m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv()) 61 return; 62 63 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA) 64 return; 65 66 CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pPageView); 67 if (!pPage) 68 return; 69 70 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 71 if (!pFormFillEnv) 72 return; 73 74 pFormFillEnv->Invalidate(static_cast<FPDF_PAGE>(pPage), 75 CFX_FloatRect::FromCFXRectF(rt).ToFxRect()); 76 } 77 78 void CPDFXFA_DocEnvironment::DisplayCaret(CXFA_FFWidget* hWidget, 79 bool bVisible, 80 const CFX_RectF* pRtAnchor) { 81 if (!hWidget || !pRtAnchor || !m_pContext->GetXFADoc() || 82 !m_pContext->GetFormFillEnv() || !m_pContext->GetXFADocView()) 83 return; 84 85 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA) 86 return; 87 88 CXFA_FFWidgetHandler* pWidgetHandler = 89 m_pContext->GetXFADocView()->GetWidgetHandler(); 90 if (!pWidgetHandler) 91 return; 92 93 CXFA_FFPageView* pPageView = hWidget->GetPageView(); 94 if (!pPageView) 95 return; 96 97 CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pPageView); 98 if (!pPage) 99 return; 100 101 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 102 if (!pFormFillEnv) 103 return; 104 105 CFX_FloatRect rcCaret = CFX_FloatRect::FromCFXRectF(*pRtAnchor); 106 pFormFillEnv->DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, 107 rcCaret.top, rcCaret.right, rcCaret.bottom); 108 } 109 110 bool CPDFXFA_DocEnvironment::GetPopupPos(CXFA_FFWidget* hWidget, 111 FX_FLOAT fMinPopup, 112 FX_FLOAT fMaxPopup, 113 const CFX_RectF& rtAnchor, 114 CFX_RectF& rtPopup) { 115 if (!hWidget) 116 return false; 117 118 CXFA_FFPageView* pXFAPageView = hWidget->GetPageView(); 119 if (!pXFAPageView) 120 return false; 121 122 CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pXFAPageView); 123 if (!pPage) 124 return false; 125 126 CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc(); 127 int nRotate = pWidgetAcc->GetRotate(); 128 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 129 if (!pFormFillEnv) 130 return false; 131 132 FS_RECTF pageViewRect = {0.0f, 0.0f, 0.0f, 0.0f}; 133 pFormFillEnv->GetPageViewRect(pPage, pageViewRect); 134 135 int t1; 136 int t2; 137 CFX_FloatRect rcAnchor = CFX_FloatRect::FromCFXRectF(rtAnchor); 138 switch (nRotate) { 139 case 90: { 140 t1 = (int)(pageViewRect.right - rcAnchor.right); 141 t2 = (int)(rcAnchor.left - pageViewRect.left); 142 if (rcAnchor.bottom < pageViewRect.bottom) 143 rtPopup.left += rcAnchor.bottom - pageViewRect.bottom; 144 break; 145 } 146 case 180: { 147 t2 = (int)(pageViewRect.top - rcAnchor.top); 148 t1 = (int)(rcAnchor.bottom - pageViewRect.bottom); 149 if (rcAnchor.left < pageViewRect.left) 150 rtPopup.left += rcAnchor.left - pageViewRect.left; 151 break; 152 } 153 case 270: { 154 t1 = (int)(rcAnchor.left - pageViewRect.left); 155 t2 = (int)(pageViewRect.right - rcAnchor.right); 156 if (rcAnchor.top > pageViewRect.top) 157 rtPopup.left -= rcAnchor.top - pageViewRect.top; 158 break; 159 } 160 case 0: 161 default: { 162 t1 = (int)(pageViewRect.top - rcAnchor.top); 163 t2 = (int)(rcAnchor.bottom - pageViewRect.bottom); 164 if (rcAnchor.right > pageViewRect.right) 165 rtPopup.left -= rcAnchor.right - pageViewRect.right; 166 break; 167 } 168 } 169 170 int t; 171 uint32_t dwPos; 172 if (t1 <= 0 && t2 <= 0) 173 return false; 174 if (t1 <= 0) { 175 t = t2; 176 dwPos = 1; 177 } else if (t2 <= 0) { 178 t = t1; 179 dwPos = 0; 180 } else if (t1 > t2) { 181 t = t1; 182 dwPos = 0; 183 } else { 184 t = t2; 185 dwPos = 1; 186 } 187 188 FX_FLOAT fPopupHeight; 189 if (t < fMinPopup) 190 fPopupHeight = fMinPopup; 191 else if (t > fMaxPopup) 192 fPopupHeight = fMaxPopup; 193 else 194 fPopupHeight = static_cast<FX_FLOAT>(t); 195 196 switch (nRotate) { 197 case 0: 198 case 180: { 199 if (dwPos == 0) { 200 rtPopup.top = rtAnchor.height; 201 rtPopup.height = fPopupHeight; 202 } else { 203 rtPopup.top = -fPopupHeight; 204 rtPopup.height = fPopupHeight; 205 } 206 break; 207 } 208 case 90: 209 case 270: { 210 if (dwPos == 0) { 211 rtPopup.top = rtAnchor.width; 212 rtPopup.height = fPopupHeight; 213 } else { 214 rtPopup.top = -fPopupHeight; 215 rtPopup.height = fPopupHeight; 216 } 217 break; 218 } 219 default: 220 break; 221 } 222 223 return true; 224 } 225 226 bool CPDFXFA_DocEnvironment::PopupMenu(CXFA_FFWidget* hWidget, 227 CFX_PointF ptPopup) { 228 if (!hWidget) 229 return false; 230 231 CXFA_FFPageView* pXFAPageView = hWidget->GetPageView(); 232 if (!pXFAPageView) 233 return false; 234 235 CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pXFAPageView); 236 if (!pPage) 237 return false; 238 239 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 240 if (!pFormFillEnv) 241 return false; 242 243 int menuFlag = 0; 244 if (hWidget->CanUndo()) 245 menuFlag |= FXFA_MENU_UNDO; 246 if (hWidget->CanRedo()) 247 menuFlag |= FXFA_MENU_REDO; 248 if (hWidget->CanPaste()) 249 menuFlag |= FXFA_MENU_PASTE; 250 if (hWidget->CanCopy()) 251 menuFlag |= FXFA_MENU_COPY; 252 if (hWidget->CanCut()) 253 menuFlag |= FXFA_MENU_CUT; 254 if (hWidget->CanSelectAll()) 255 menuFlag |= FXFA_MENU_SELECTALL; 256 257 return pFormFillEnv->PopupMenu(pPage, hWidget, menuFlag, ptPopup); 258 } 259 260 void CPDFXFA_DocEnvironment::PageViewEvent(CXFA_FFPageView* pPageView, 261 uint32_t dwFlags) { 262 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 263 if (!pFormFillEnv) 264 return; 265 266 if (m_pContext->GetLoadStatus() == FXFA_LOADSTATUS_LOADING || 267 m_pContext->GetLoadStatus() == FXFA_LOADSTATUS_CLOSING || 268 XFA_PAGEVIEWEVENT_StopLayout != dwFlags) 269 return; 270 271 int nNewCount = m_pContext->GetPageCount(); 272 if (nNewCount == m_pContext->GetOriginalPageCount()) 273 return; 274 275 CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView(); 276 if (!pXFADocView) 277 return; 278 279 for (int iPageIter = 0; iPageIter < m_pContext->GetOriginalPageCount(); 280 iPageIter++) { 281 CPDFXFA_Page* pPage = (*m_pContext->GetXFAPageList())[iPageIter]; 282 if (!pPage) 283 continue; 284 285 m_pContext->GetFormFillEnv()->RemovePageView(pPage); 286 pPage->SetXFAPageView(pXFADocView->GetPageView(iPageIter)); 287 } 288 289 int flag = (nNewCount < m_pContext->GetOriginalPageCount()) 290 ? FXFA_PAGEVIEWEVENT_POSTREMOVED 291 : FXFA_PAGEVIEWEVENT_POSTADDED; 292 int count = FXSYS_abs(nNewCount - m_pContext->GetOriginalPageCount()); 293 m_pContext->SetOriginalPageCount(nNewCount); 294 pFormFillEnv->PageEvent(count, flag); 295 } 296 297 void CPDFXFA_DocEnvironment::WidgetPostAdd(CXFA_FFWidget* hWidget, 298 CXFA_WidgetAcc* pWidgetData) { 299 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA || !hWidget) 300 return; 301 302 CXFA_FFPageView* pPageView = hWidget->GetPageView(); 303 if (!pPageView) 304 return; 305 306 CPDFXFA_Page* pXFAPage = m_pContext->GetXFAPage(pPageView); 307 if (!pXFAPage) 308 return; 309 310 m_pContext->GetFormFillEnv()->GetPageView(pXFAPage, true)->AddAnnot(hWidget); 311 } 312 313 void CPDFXFA_DocEnvironment::WidgetPreRemove(CXFA_FFWidget* hWidget, 314 CXFA_WidgetAcc* pWidgetData) { 315 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA || !hWidget) 316 return; 317 318 CXFA_FFPageView* pPageView = hWidget->GetPageView(); 319 if (!pPageView) 320 return; 321 322 CPDFXFA_Page* pXFAPage = m_pContext->GetXFAPage(pPageView); 323 if (!pXFAPage) 324 return; 325 326 CPDFSDK_PageView* pSdkPageView = 327 m_pContext->GetFormFillEnv()->GetPageView(pXFAPage, true); 328 if (CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget)) 329 pSdkPageView->DeleteAnnot(pAnnot); 330 } 331 332 int32_t CPDFXFA_DocEnvironment::CountPages(CXFA_FFDoc* hDoc) { 333 if (hDoc == m_pContext->GetXFADoc() && m_pContext->GetFormFillEnv()) 334 return m_pContext->GetPageCount(); 335 return 0; 336 } 337 338 int32_t CPDFXFA_DocEnvironment::GetCurrentPage(CXFA_FFDoc* hDoc) { 339 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv()) 340 return -1; 341 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA) 342 return -1; 343 344 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 345 if (!pFormFillEnv) 346 return -1; 347 348 return pFormFillEnv->GetCurrentPageIndex(this); 349 } 350 351 void CPDFXFA_DocEnvironment::SetCurrentPage(CXFA_FFDoc* hDoc, 352 int32_t iCurPage) { 353 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv() || 354 m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA || iCurPage < 0 || 355 iCurPage >= m_pContext->GetFormFillEnv()->GetPageCount()) { 356 return; 357 } 358 359 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 360 if (!pFormFillEnv) 361 return; 362 pFormFillEnv->SetCurrentPage(this, iCurPage); 363 } 364 365 bool CPDFXFA_DocEnvironment::IsCalculationsEnabled(CXFA_FFDoc* hDoc) { 366 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv()) 367 return false; 368 if (m_pContext->GetFormFillEnv()->GetInterForm()) { 369 return m_pContext->GetFormFillEnv() 370 ->GetInterForm() 371 ->IsXfaCalculateEnabled(); 372 } 373 return false; 374 } 375 376 void CPDFXFA_DocEnvironment::SetCalculationsEnabled(CXFA_FFDoc* hDoc, 377 bool bEnabled) { 378 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv()) 379 return; 380 if (m_pContext->GetFormFillEnv()->GetInterForm()) { 381 m_pContext->GetFormFillEnv()->GetInterForm()->XfaEnableCalculate(bEnabled); 382 } 383 } 384 385 void CPDFXFA_DocEnvironment::GetTitle(CXFA_FFDoc* hDoc, 386 CFX_WideString& wsTitle) { 387 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetPDFDoc()) 388 return; 389 390 CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo(); 391 if (!pInfoDict) 392 return; 393 394 CFX_ByteString csTitle = pInfoDict->GetStringFor("Title"); 395 wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength())); 396 csTitle.ReleaseBuffer(csTitle.GetLength()); 397 } 398 399 void CPDFXFA_DocEnvironment::SetTitle(CXFA_FFDoc* hDoc, 400 const CFX_WideString& wsTitle) { 401 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetPDFDoc()) 402 return; 403 404 if (CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo()) 405 pInfoDict->SetNewFor<CPDF_String>("Title", wsTitle); 406 } 407 408 void CPDFXFA_DocEnvironment::ExportData(CXFA_FFDoc* hDoc, 409 const CFX_WideString& wsFilePath, 410 bool bXDP) { 411 if (hDoc != m_pContext->GetXFADoc()) 412 return; 413 414 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && 415 m_pContext->GetDocType() != DOCTYPE_STATIC_XFA) { 416 return; 417 } 418 419 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 420 if (!pFormFillEnv) 421 return; 422 423 int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML; 424 CFX_ByteString bs = wsFilePath.UTF16LE_Encode(); 425 if (wsFilePath.IsEmpty()) { 426 if (!pFormFillEnv->GetFormFillInfo() || 427 !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform) { 428 return; 429 } 430 431 CFX_WideString filepath = pFormFillEnv->JS_fieldBrowse(); 432 bs = filepath.UTF16LE_Encode(); 433 } 434 int len = bs.GetLength(); 435 FPDF_FILEHANDLER* pFileHandler = 436 pFormFillEnv->OpenFile(bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML, 437 (FPDF_WIDESTRING)bs.GetBuffer(len), "wb"); 438 bs.ReleaseBuffer(len); 439 if (!pFileHandler) 440 return; 441 442 CFX_RetainPtr<IFX_SeekableStream> fileWrite = 443 MakeSeekableStream(pFileHandler); 444 CFX_ByteString content; 445 if (fileType == FXFA_SAVEAS_XML) { 446 content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"; 447 fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(), 448 content.GetLength()); 449 m_pContext->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Data, 450 fileWrite, nullptr); 451 } else if (fileType == FXFA_SAVEAS_XDP) { 452 if (!m_pContext->GetPDFDoc()) 453 return; 454 455 CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot(); 456 if (!pRoot) 457 return; 458 459 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm"); 460 if (!pAcroForm) 461 return; 462 463 CPDF_Array* pArray = ToArray(pAcroForm->GetObjectFor("XFA")); 464 if (!pArray) 465 return; 466 467 int size = pArray->GetCount(); 468 for (int i = 1; i < size; i += 2) { 469 CPDF_Object* pPDFObj = pArray->GetObjectAt(i); 470 CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1); 471 if (!pPrePDFObj->IsString()) 472 continue; 473 if (!pPDFObj->IsReference()) 474 continue; 475 476 CPDF_Stream* pStream = ToStream(pPDFObj->GetDirect()); 477 if (!pStream) 478 continue; 479 if (pPrePDFObj->GetString() == "form") { 480 m_pContext->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Form, 481 fileWrite, nullptr); 482 continue; 483 } 484 if (pPrePDFObj->GetString() == "datasets") { 485 m_pContext->GetXFADocView()->GetDoc()->SavePackage( 486 XFA_HASHCODE_Datasets, fileWrite, nullptr); 487 continue; 488 } 489 if (i == size - 1) { 490 CFX_WideString wPath = CFX_WideString::FromUTF16LE( 491 reinterpret_cast<const unsigned short*>(bs.c_str()), 492 bs.GetLength() / sizeof(unsigned short)); 493 CFX_ByteString bPath = wPath.UTF8Encode(); 494 const char* szFormat = 495 "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>"; 496 content.Format(szFormat, bPath.c_str()); 497 fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(), 498 content.GetLength()); 499 } 500 std::unique_ptr<CPDF_StreamAcc> pAcc(new CPDF_StreamAcc); 501 pAcc->LoadAllData(pStream); 502 fileWrite->WriteBlock(pAcc->GetData(), fileWrite->GetSize(), 503 pAcc->GetSize()); 504 } 505 } 506 fileWrite->Flush(); 507 } 508 509 void CPDFXFA_DocEnvironment::GotoURL(CXFA_FFDoc* hDoc, 510 const CFX_WideString& bsURL) { 511 if (hDoc != m_pContext->GetXFADoc()) 512 return; 513 514 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA) 515 return; 516 517 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 518 if (!pFormFillEnv) 519 return; 520 521 CFX_WideStringC str(bsURL.c_str()); 522 pFormFillEnv->GotoURL(this, str); 523 } 524 525 bool CPDFXFA_DocEnvironment::IsValidationsEnabled(CXFA_FFDoc* hDoc) { 526 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv()) 527 return false; 528 if (m_pContext->GetFormFillEnv()->GetInterForm()) { 529 return m_pContext->GetFormFillEnv() 530 ->GetInterForm() 531 ->IsXfaValidationsEnabled(); 532 } 533 return true; 534 } 535 536 void CPDFXFA_DocEnvironment::SetValidationsEnabled(CXFA_FFDoc* hDoc, 537 bool bEnabled) { 538 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv()) 539 return; 540 if (m_pContext->GetFormFillEnv()->GetInterForm()) { 541 m_pContext->GetFormFillEnv()->GetInterForm()->XfaSetValidationsEnabled( 542 bEnabled); 543 } 544 } 545 546 void CPDFXFA_DocEnvironment::SetFocusWidget(CXFA_FFDoc* hDoc, 547 CXFA_FFWidget* hWidget) { 548 if (hDoc != m_pContext->GetXFADoc()) 549 return; 550 551 if (!hWidget) { 552 CPDFSDK_Annot::ObservedPtr pNull; 553 m_pContext->GetFormFillEnv()->SetFocusAnnot(&pNull); 554 return; 555 } 556 557 int pageViewCount = m_pContext->GetFormFillEnv()->GetPageViewCount(); 558 for (int i = 0; i < pageViewCount; i++) { 559 CPDFSDK_PageView* pPageView = m_pContext->GetFormFillEnv()->GetPageView(i); 560 if (!pPageView) 561 continue; 562 563 CPDFSDK_Annot::ObservedPtr pAnnot(pPageView->GetAnnotByXFAWidget(hWidget)); 564 if (pAnnot) { 565 m_pContext->GetFormFillEnv()->SetFocusAnnot(&pAnnot); 566 break; 567 } 568 } 569 } 570 571 void CPDFXFA_DocEnvironment::Print(CXFA_FFDoc* hDoc, 572 int32_t nStartPage, 573 int32_t nEndPage, 574 uint32_t dwOptions) { 575 if (hDoc != m_pContext->GetXFADoc()) 576 return; 577 578 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 579 if (!pFormFillEnv || !pFormFillEnv->GetFormFillInfo() || 580 !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform || 581 !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print) { 582 return; 583 } 584 585 pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print( 586 pFormFillEnv->GetFormFillInfo()->m_pJsPlatform, 587 dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage, 588 dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage, 589 dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder, 590 dwOptions & XFA_PRINTOPT_PrintAnnot); 591 } 592 593 FX_ARGB CPDFXFA_DocEnvironment::GetHighlightColor(CXFA_FFDoc* hDoc) { 594 if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv()) 595 return 0; 596 597 CPDFSDK_InterForm* pInterForm = m_pContext->GetFormFillEnv()->GetInterForm(); 598 if (!pInterForm) 599 return 0; 600 601 return ArgbEncode(pInterForm->GetHighlightAlpha(), 602 pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA)); 603 } 604 605 bool CPDFXFA_DocEnvironment::NotifySubmit(bool bPrevOrPost) { 606 if (bPrevOrPost) 607 return OnBeforeNotifySubmit(); 608 609 OnAfterNotifySubmit(); 610 return true; 611 } 612 613 bool CPDFXFA_DocEnvironment::OnBeforeNotifySubmit() { 614 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && 615 m_pContext->GetDocType() != DOCTYPE_STATIC_XFA) { 616 return true; 617 } 618 619 if (!m_pContext->GetXFADocView()) 620 return true; 621 622 CXFA_FFWidgetHandler* pWidgetHandler = 623 m_pContext->GetXFADocView()->GetWidgetHandler(); 624 if (!pWidgetHandler) 625 return true; 626 627 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator( 628 m_pContext->GetXFADocView()->CreateWidgetAccIterator()); 629 if (pWidgetAccIterator) { 630 CXFA_EventParam Param; 631 Param.m_eType = XFA_EVENT_PreSubmit; 632 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) 633 pWidgetHandler->ProcessEvent(pWidgetAcc, &Param); 634 } 635 636 pWidgetAccIterator.reset( 637 m_pContext->GetXFADocView()->CreateWidgetAccIterator()); 638 if (!pWidgetAccIterator) 639 return true; 640 641 CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); 642 pWidgetAcc = pWidgetAccIterator->MoveToNext(); 643 while (pWidgetAcc) { 644 int fRet = pWidgetAcc->ProcessValidate(-1); 645 if (fRet == XFA_EVENTERROR_Error) { 646 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 647 if (!pFormFillEnv) 648 return false; 649 650 CFX_WideString ws; 651 ws.FromLocal(IDS_XFA_Validate_Input); 652 CFX_ByteString bs = ws.UTF16LE_Encode(); 653 int len = bs.GetLength(); 654 pFormFillEnv->Alert((FPDF_WIDESTRING)bs.GetBuffer(len), 655 (FPDF_WIDESTRING)L"", 0, 1); 656 bs.ReleaseBuffer(len); 657 return false; 658 } 659 pWidgetAcc = pWidgetAccIterator->MoveToNext(); 660 } 661 m_pContext->GetXFADocView()->UpdateDocView(); 662 663 return true; 664 } 665 666 void CPDFXFA_DocEnvironment::OnAfterNotifySubmit() { 667 if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && 668 m_pContext->GetDocType() != DOCTYPE_STATIC_XFA) 669 return; 670 671 if (!m_pContext->GetXFADocView()) 672 return; 673 674 CXFA_FFWidgetHandler* pWidgetHandler = 675 m_pContext->GetXFADocView()->GetWidgetHandler(); 676 if (!pWidgetHandler) 677 return; 678 679 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator( 680 m_pContext->GetXFADocView()->CreateWidgetAccIterator()); 681 if (!pWidgetAccIterator) 682 return; 683 684 CXFA_EventParam Param; 685 Param.m_eType = XFA_EVENT_PostSubmit; 686 CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); 687 while (pWidgetAcc) { 688 pWidgetHandler->ProcessEvent(pWidgetAcc, &Param); 689 pWidgetAcc = pWidgetAccIterator->MoveToNext(); 690 } 691 m_pContext->GetXFADocView()->UpdateDocView(); 692 } 693 694 bool CPDFXFA_DocEnvironment::SubmitData(CXFA_FFDoc* hDoc, CXFA_Submit submit) { 695 if (!NotifySubmit(true) || !m_pContext->GetXFADocView()) 696 return false; 697 698 m_pContext->GetXFADocView()->UpdateDocView(); 699 bool ret = SubmitDataInternal(hDoc, submit); 700 NotifySubmit(false); 701 return ret; 702 } 703 704 CFX_RetainPtr<IFX_SeekableReadStream> CPDFXFA_DocEnvironment::OpenLinkedFile( 705 CXFA_FFDoc* hDoc, 706 const CFX_WideString& wsLink) { 707 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 708 if (!pFormFillEnv) 709 return nullptr; 710 711 CFX_ByteString bs = wsLink.UTF16LE_Encode(); 712 int len = bs.GetLength(); 713 FPDF_FILEHANDLER* pFileHandler = 714 pFormFillEnv->OpenFile(0, (FPDF_WIDESTRING)bs.GetBuffer(len), "rb"); 715 bs.ReleaseBuffer(len); 716 if (!pFileHandler) 717 return nullptr; 718 719 return MakeSeekableStream(pFileHandler); 720 } 721 722 bool CPDFXFA_DocEnvironment::ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler, 723 int fileType, 724 FPDF_DWORD encodeType, 725 FPDF_DWORD flag) { 726 if (!m_pContext->GetXFADocView()) 727 return false; 728 729 CFX_ByteString content; 730 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 731 if (!pFormFillEnv) 732 return false; 733 734 CFX_RetainPtr<IFX_SeekableStream> fileStream = 735 MakeSeekableStream(pFileHandler); 736 737 if (fileType == FXFA_SAVEAS_XML) { 738 const char kContent[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"; 739 fileStream->WriteBlock(kContent, 0, strlen(kContent)); 740 m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Data, fileStream, 741 nullptr); 742 return true; 743 } 744 745 if (fileType != FXFA_SAVEAS_XDP) 746 return true; 747 748 if (!flag) { 749 flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS | 750 FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM; 751 } 752 if (!m_pContext->GetPDFDoc()) { 753 fileStream->Flush(); 754 return false; 755 } 756 757 CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot(); 758 if (!pRoot) { 759 fileStream->Flush(); 760 return false; 761 } 762 763 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm"); 764 if (!pAcroForm) { 765 fileStream->Flush(); 766 return false; 767 } 768 769 CPDF_Array* pArray = ToArray(pAcroForm->GetObjectFor("XFA")); 770 if (!pArray) { 771 fileStream->Flush(); 772 return false; 773 } 774 775 int size = pArray->GetCount(); 776 for (int i = 1; i < size; i += 2) { 777 CPDF_Object* pPDFObj = pArray->GetObjectAt(i); 778 CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1); 779 if (!pPrePDFObj->IsString()) 780 continue; 781 if (!pPDFObj->IsReference()) 782 continue; 783 784 CPDF_Object* pDirectObj = pPDFObj->GetDirect(); 785 if (!pDirectObj->IsStream()) 786 continue; 787 if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG)) 788 continue; 789 if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE)) 790 continue; 791 if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET)) 792 continue; 793 if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS)) 794 continue; 795 if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA)) 796 continue; 797 if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF)) 798 continue; 799 if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM)) 800 continue; 801 if (pPrePDFObj->GetString() == "form") { 802 m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Form, fileStream, 803 nullptr); 804 } else if (pPrePDFObj->GetString() == "datasets") { 805 m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Datasets, fileStream, 806 nullptr); 807 } else { 808 // PDF,creator. 809 } 810 } 811 return true; 812 } 813 814 void CPDFXFA_DocEnvironment::ToXFAContentFlags(CFX_WideString csSrcContent, 815 FPDF_DWORD& flag) { 816 if (csSrcContent.Find(L" config ", 0) != -1) 817 flag |= FXFA_CONFIG; 818 if (csSrcContent.Find(L" template ", 0) != -1) 819 flag |= FXFA_TEMPLATE; 820 if (csSrcContent.Find(L" localeSet ", 0) != -1) 821 flag |= FXFA_LOCALESET; 822 if (csSrcContent.Find(L" datasets ", 0) != -1) 823 flag |= FXFA_DATASETS; 824 if (csSrcContent.Find(L" xmpmeta ", 0) != -1) 825 flag |= FXFA_XMPMETA; 826 if (csSrcContent.Find(L" xfdf ", 0) != -1) 827 flag |= FXFA_XFDF; 828 if (csSrcContent.Find(L" form ", 0) != -1) 829 flag |= FXFA_FORM; 830 if (flag == 0) { 831 flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS | 832 FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM; 833 } 834 } 835 836 bool CPDFXFA_DocEnvironment::MailToInfo(CFX_WideString& csURL, 837 CFX_WideString& csToAddress, 838 CFX_WideString& csCCAddress, 839 CFX_WideString& csBCCAddress, 840 CFX_WideString& csSubject, 841 CFX_WideString& csMsg) { 842 CFX_WideString srcURL = csURL; 843 srcURL.TrimLeft(); 844 if (srcURL.Left(7).CompareNoCase(L"mailto:") != 0) 845 return false; 846 847 int pos = srcURL.Find(L'?', 0); 848 CFX_WideString tmp; 849 if (pos == -1) { 850 pos = srcURL.Find(L'@', 0); 851 if (pos == -1) 852 return false; 853 854 tmp = srcURL.Right(csURL.GetLength() - 7); 855 } else { 856 tmp = srcURL.Left(pos); 857 tmp = tmp.Right(tmp.GetLength() - 7); 858 } 859 tmp.TrimLeft(); 860 tmp.TrimRight(); 861 862 csToAddress = tmp; 863 864 srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1)); 865 while (!srcURL.IsEmpty()) { 866 srcURL.TrimLeft(); 867 srcURL.TrimRight(); 868 pos = srcURL.Find(L'&', 0); 869 870 tmp = (pos == -1) ? srcURL : srcURL.Left(pos); 871 tmp.TrimLeft(); 872 tmp.TrimRight(); 873 if (tmp.GetLength() >= 3 && tmp.Left(3).CompareNoCase(L"cc=") == 0) { 874 tmp = tmp.Right(tmp.GetLength() - 3); 875 if (!csCCAddress.IsEmpty()) 876 csCCAddress += L';'; 877 csCCAddress += tmp; 878 } else if (tmp.GetLength() >= 4 && 879 tmp.Left(4).CompareNoCase(L"bcc=") == 0) { 880 tmp = tmp.Right(tmp.GetLength() - 4); 881 if (!csBCCAddress.IsEmpty()) 882 csBCCAddress += L';'; 883 csBCCAddress += tmp; 884 } else if (tmp.GetLength() >= 8 && 885 tmp.Left(8).CompareNoCase(L"subject=") == 0) { 886 tmp = tmp.Right(tmp.GetLength() - 8); 887 csSubject += tmp; 888 } else if (tmp.GetLength() >= 5 && 889 tmp.Left(5).CompareNoCase(L"body=") == 0) { 890 tmp = tmp.Right(tmp.GetLength() - 5); 891 csMsg += tmp; 892 } 893 srcURL = (pos == -1) ? L"" : srcURL.Right(csURL.GetLength() - (pos + 1)); 894 } 895 csToAddress.Replace(L",", L";"); 896 csCCAddress.Replace(L",", L";"); 897 csBCCAddress.Replace(L",", L";"); 898 return true; 899 } 900 901 bool CPDFXFA_DocEnvironment::SubmitDataInternal(CXFA_FFDoc* hDoc, 902 CXFA_Submit submit) { 903 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 904 if (!pFormFillEnv) 905 return false; 906 907 CFX_WideStringC csURLC; 908 submit.GetSubmitTarget(csURLC); 909 CFX_WideString csURL(csURLC); 910 if (csURL.IsEmpty()) { 911 CFX_WideString ws; 912 ws.FromLocal("Submit cancelled."); 913 CFX_ByteString bs = ws.UTF16LE_Encode(); 914 int len = bs.GetLength(); 915 pFormFillEnv->Alert((FPDF_WIDESTRING)bs.GetBuffer(len), 916 (FPDF_WIDESTRING)L"", 0, 4); 917 bs.ReleaseBuffer(len); 918 return false; 919 } 920 921 FPDF_FILEHANDLER* pFileHandler = nullptr; 922 int fileFlag = -1; 923 switch (submit.GetSubmitFormat()) { 924 case XFA_ATTRIBUTEENUM_Xdp: { 925 CFX_WideStringC csContentC; 926 submit.GetSubmitXDPContent(csContentC); 927 CFX_WideString csContent; 928 csContent = csContentC; 929 csContent.TrimLeft(); 930 csContent.TrimRight(); 931 CFX_WideString space; 932 space.FromLocal(" "); 933 csContent = space + csContent + space; 934 FPDF_DWORD flag = 0; 935 if (submit.IsSubmitEmbedPDF()) 936 flag |= FXFA_PDF; 937 938 ToXFAContentFlags(csContent, flag); 939 pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XDP, nullptr, "wb"); 940 fileFlag = FXFA_SAVEAS_XDP; 941 ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag); 942 break; 943 } 944 case XFA_ATTRIBUTEENUM_Xml: 945 pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XML, nullptr, "wb"); 946 fileFlag = FXFA_SAVEAS_XML; 947 ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL); 948 break; 949 case XFA_ATTRIBUTEENUM_Pdf: 950 break; 951 case XFA_ATTRIBUTEENUM_Urlencoded: 952 pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XML, nullptr, "wb"); 953 fileFlag = FXFA_SAVEAS_XML; 954 ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL); 955 break; 956 default: 957 return false; 958 } 959 if (!pFileHandler) 960 return false; 961 if (csURL.Left(7).CompareNoCase(L"mailto:") == 0) { 962 CFX_WideString csToAddress; 963 CFX_WideString csCCAddress; 964 CFX_WideString csBCCAddress; 965 CFX_WideString csSubject; 966 CFX_WideString csMsg; 967 if (!MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject, 968 csMsg)) { 969 return false; 970 } 971 CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode(); 972 CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode(); 973 CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode(); 974 CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode(); 975 CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode(); 976 FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength()); 977 FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength()); 978 FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength()); 979 FPDF_WIDESTRING pSubject = 980 (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength()); 981 FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength()); 982 pFormFillEnv->EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg); 983 bsTo.ReleaseBuffer(); 984 bsCC.ReleaseBuffer(); 985 bsBcc.ReleaseBuffer(); 986 bsSubject.ReleaseBuffer(); 987 bsMsg.ReleaseBuffer(); 988 } else { 989 // HTTP or FTP 990 CFX_WideString ws; 991 CFX_ByteString bs = csURL.UTF16LE_Encode(); 992 int len = bs.GetLength(); 993 pFormFillEnv->UploadTo(pFileHandler, fileFlag, 994 (FPDF_WIDESTRING)bs.GetBuffer(len)); 995 bs.ReleaseBuffer(len); 996 } 997 return true; 998 } 999 1000 bool CPDFXFA_DocEnvironment::SetGlobalProperty( 1001 CXFA_FFDoc* hDoc, 1002 const CFX_ByteStringC& szPropName, 1003 CFXJSE_Value* pValue) { 1004 if (hDoc != m_pContext->GetXFADoc()) 1005 return false; 1006 1007 if (m_pContext->GetFormFillEnv() && 1008 m_pContext->GetFormFillEnv()->GetJSRuntime()) { 1009 return m_pContext->GetFormFillEnv()->GetJSRuntime()->SetValueByName( 1010 szPropName, pValue); 1011 } 1012 return false; 1013 } 1014 1015 bool CPDFXFA_DocEnvironment::GetGlobalProperty( 1016 CXFA_FFDoc* hDoc, 1017 const CFX_ByteStringC& szPropName, 1018 CFXJSE_Value* pValue) { 1019 if (hDoc != m_pContext->GetXFADoc()) 1020 return false; 1021 if (!m_pContext->GetFormFillEnv() || 1022 !m_pContext->GetFormFillEnv()->GetJSRuntime()) { 1023 return false; 1024 } 1025 1026 CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); 1027 if (!m_pJSEventContext) 1028 m_pJSEventContext = pFormFillEnv->GetJSRuntime()->NewEventContext(); 1029 1030 return pFormFillEnv->GetJSRuntime()->GetValueByName(szPropName, pValue); 1031 } 1032