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_formfillenvironment.h" 8 9 #include <memory> 10 #include <utility> 11 12 #include "core/fpdfapi/parser/cpdf_array.h" 13 #include "core/fpdfdoc/cpdf_docjsactions.h" 14 #include "fpdfsdk/cpdfsdk_annothandlermgr.h" 15 #include "fpdfsdk/cpdfsdk_interform.h" 16 #include "fpdfsdk/cpdfsdk_pageview.h" 17 #include "fpdfsdk/cpdfsdk_widget.h" 18 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h" 19 #include "fpdfsdk/fsdk_actionhandler.h" 20 #include "fxjs/ijs_runtime.h" 21 #include "third_party/base/ptr_util.h" 22 23 namespace { 24 25 // NOTE: |bsUTF16LE| must outlive the use of the result. Care must be taken 26 // since modifying the result would impact |bsUTF16LE|. 27 FPDF_WIDESTRING AsFPDFWideString(ByteString* bsUTF16LE) { 28 return reinterpret_cast<FPDF_WIDESTRING>( 29 bsUTF16LE->GetBuffer(bsUTF16LE->GetLength())); 30 } 31 32 } // namespace 33 34 CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment( 35 UnderlyingDocumentType* pDoc, 36 FPDF_FORMFILLINFO* pFFinfo) 37 : m_pInfo(pFFinfo), 38 m_pUnderlyingDoc(pDoc), 39 m_pSysHandler(pdfium::MakeUnique<CFX_SystemHandler>(this)), 40 m_bChangeMask(false), 41 m_bBeingDestroyed(false) {} 42 43 CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() { 44 m_bBeingDestroyed = true; 45 ClearAllFocusedAnnots(); 46 47 // |m_PageMap| will try to access |m_pInterForm| when it cleans itself up. 48 // Make sure it is deleted before |m_pInterForm|. 49 m_PageMap.clear(); 50 51 // |m_pAnnotHandlerMgr| will try to access |m_pFormFiller| when it cleans 52 // itself up. Make sure it is deleted before |m_pFormFiller|. 53 m_pAnnotHandlerMgr.reset(); 54 55 // Must destroy the |m_pFormFiller| before the environment (|this|) 56 // because any created form widgets hold a pointer to the environment. 57 // Those widgets may call things like KillTimer() as they are shutdown. 58 m_pFormFiller.reset(); 59 60 if (m_pInfo && m_pInfo->Release) 61 m_pInfo->Release(m_pInfo); 62 } 63 64 int CPDFSDK_FormFillEnvironment::JS_appAlert(const wchar_t* Msg, 65 const wchar_t* Title, 66 uint32_t Type, 67 uint32_t Icon) { 68 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 69 !m_pInfo->m_pJsPlatform->app_alert) { 70 return -1; 71 } 72 ByteString bsMsg = WideString(Msg).UTF16LE_Encode(); 73 ByteString bsTitle = WideString(Title).UTF16LE_Encode(); 74 return m_pInfo->m_pJsPlatform->app_alert( 75 m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsMsg), 76 AsFPDFWideString(&bsTitle), Type, Icon); 77 } 78 79 int CPDFSDK_FormFillEnvironment::JS_appResponse(const wchar_t* Question, 80 const wchar_t* Title, 81 const wchar_t* Default, 82 const wchar_t* cLabel, 83 FPDF_BOOL bPassword, 84 void* response, 85 int length) { 86 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 87 !m_pInfo->m_pJsPlatform->app_response) { 88 return -1; 89 } 90 ByteString bsQuestion = WideString(Question).UTF16LE_Encode(); 91 ByteString bsTitle = WideString(Title).UTF16LE_Encode(); 92 ByteString bsDefault = WideString(Default).UTF16LE_Encode(); 93 ByteString bsLabel = WideString(cLabel).UTF16LE_Encode(); 94 return m_pInfo->m_pJsPlatform->app_response( 95 m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsQuestion), 96 AsFPDFWideString(&bsTitle), AsFPDFWideString(&bsDefault), 97 AsFPDFWideString(&bsLabel), bPassword, response, length); 98 } 99 100 void CPDFSDK_FormFillEnvironment::JS_appBeep(int nType) { 101 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 102 !m_pInfo->m_pJsPlatform->app_beep) { 103 return; 104 } 105 m_pInfo->m_pJsPlatform->app_beep(m_pInfo->m_pJsPlatform, nType); 106 } 107 108 WideString CPDFSDK_FormFillEnvironment::JS_fieldBrowse() { 109 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 110 !m_pInfo->m_pJsPlatform->Field_browse) { 111 return WideString(); 112 } 113 const int nRequiredLen = 114 m_pInfo->m_pJsPlatform->Field_browse(m_pInfo->m_pJsPlatform, nullptr, 0); 115 if (nRequiredLen <= 0) 116 return WideString(); 117 118 std::vector<uint8_t> pBuff(nRequiredLen); 119 const int nActualLen = m_pInfo->m_pJsPlatform->Field_browse( 120 m_pInfo->m_pJsPlatform, pBuff.data(), nRequiredLen); 121 if (nActualLen <= 0 || nActualLen > nRequiredLen) 122 return WideString(); 123 124 pBuff.resize(nActualLen); 125 return WideString::FromLocal(ByteStringView(pBuff)); 126 } 127 128 WideString CPDFSDK_FormFillEnvironment::JS_docGetFilePath() { 129 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 130 !m_pInfo->m_pJsPlatform->Doc_getFilePath) { 131 return WideString(); 132 } 133 const int nRequiredLen = m_pInfo->m_pJsPlatform->Doc_getFilePath( 134 m_pInfo->m_pJsPlatform, nullptr, 0); 135 if (nRequiredLen <= 0) 136 return WideString(); 137 138 std::vector<uint8_t> pBuff(nRequiredLen); 139 const int nActualLen = m_pInfo->m_pJsPlatform->Doc_getFilePath( 140 m_pInfo->m_pJsPlatform, pBuff.data(), nRequiredLen); 141 if (nActualLen <= 0 || nActualLen > nRequiredLen) 142 return WideString(); 143 144 pBuff.resize(nActualLen); 145 return WideString::FromLocal(ByteStringView(pBuff)); 146 } 147 148 void CPDFSDK_FormFillEnvironment::JS_docSubmitForm(void* formData, 149 int length, 150 const wchar_t* URL) { 151 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 152 !m_pInfo->m_pJsPlatform->Doc_submitForm) { 153 return; 154 } 155 ByteString bsDestination = WideString(URL).UTF16LE_Encode(); 156 m_pInfo->m_pJsPlatform->Doc_submitForm(m_pInfo->m_pJsPlatform, formData, 157 length, 158 AsFPDFWideString(&bsDestination)); 159 } 160 161 void CPDFSDK_FormFillEnvironment::JS_docmailForm(void* mailData, 162 int length, 163 FPDF_BOOL bUI, 164 const wchar_t* To, 165 const wchar_t* Subject, 166 const wchar_t* CC, 167 const wchar_t* BCC, 168 const wchar_t* Msg) { 169 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 170 !m_pInfo->m_pJsPlatform->Doc_mail) { 171 return; 172 } 173 ByteString bsTo = WideString(To).UTF16LE_Encode(); 174 ByteString bsSubject = WideString(Subject).UTF16LE_Encode(); 175 ByteString bsCC = WideString(CC).UTF16LE_Encode(); 176 ByteString bsBcc = WideString(BCC).UTF16LE_Encode(); 177 ByteString bsMsg = WideString(Msg).UTF16LE_Encode(); 178 m_pInfo->m_pJsPlatform->Doc_mail( 179 m_pInfo->m_pJsPlatform, mailData, length, bUI, AsFPDFWideString(&bsTo), 180 AsFPDFWideString(&bsSubject), AsFPDFWideString(&bsCC), 181 AsFPDFWideString(&bsBcc), AsFPDFWideString(&bsMsg)); 182 } 183 184 void CPDFSDK_FormFillEnvironment::JS_docprint(FPDF_BOOL bUI, 185 int nStart, 186 int nEnd, 187 FPDF_BOOL bSilent, 188 FPDF_BOOL bShrinkToFit, 189 FPDF_BOOL bPrintAsImage, 190 FPDF_BOOL bReverse, 191 FPDF_BOOL bAnnotations) { 192 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 193 !m_pInfo->m_pJsPlatform->Doc_print) { 194 return; 195 } 196 m_pInfo->m_pJsPlatform->Doc_print(m_pInfo->m_pJsPlatform, bUI, nStart, nEnd, 197 bSilent, bShrinkToFit, bPrintAsImage, 198 bReverse, bAnnotations); 199 } 200 201 void CPDFSDK_FormFillEnvironment::JS_docgotoPage(int nPageNum) { 202 if (!m_pInfo || !m_pInfo->m_pJsPlatform || 203 !m_pInfo->m_pJsPlatform->Doc_gotoPage) { 204 return; 205 } 206 m_pInfo->m_pJsPlatform->Doc_gotoPage(m_pInfo->m_pJsPlatform, nPageNum); 207 } 208 209 IJS_Runtime* CPDFSDK_FormFillEnvironment::GetJSRuntime() { 210 if (!IsJSInitiated()) 211 return nullptr; 212 if (!m_pJSRuntime) 213 m_pJSRuntime.reset(IJS_Runtime::Create(this)); 214 return m_pJSRuntime.get(); 215 } 216 217 CPDFSDK_AnnotHandlerMgr* CPDFSDK_FormFillEnvironment::GetAnnotHandlerMgr() { 218 if (!m_pAnnotHandlerMgr) 219 m_pAnnotHandlerMgr = pdfium::MakeUnique<CPDFSDK_AnnotHandlerMgr>(this); 220 return m_pAnnotHandlerMgr.get(); 221 } 222 223 CPDFSDK_ActionHandler* CPDFSDK_FormFillEnvironment::GetActionHandler() { 224 if (!m_pActionHandler) 225 m_pActionHandler = pdfium::MakeUnique<CPDFSDK_ActionHandler>(); 226 return m_pActionHandler.get(); 227 } 228 229 CFFL_InteractiveFormFiller* 230 CPDFSDK_FormFillEnvironment::GetInteractiveFormFiller() { 231 if (!m_pFormFiller) 232 m_pFormFiller = pdfium::MakeUnique<CFFL_InteractiveFormFiller>(this); 233 return m_pFormFiller.get(); 234 } 235 236 void CPDFSDK_FormFillEnvironment::Invalidate(UnderlyingPageType* page, 237 const FX_RECT& rect) { 238 if (m_pInfo && m_pInfo->FFI_Invalidate) { 239 m_pInfo->FFI_Invalidate(m_pInfo, page, rect.left, rect.top, rect.right, 240 rect.bottom); 241 } 242 } 243 244 void CPDFSDK_FormFillEnvironment::OutputSelectedRect( 245 UnderlyingPageType* page, 246 const CFX_FloatRect& rect) { 247 if (m_pInfo && m_pInfo->FFI_OutputSelectedRect) { 248 m_pInfo->FFI_OutputSelectedRect(m_pInfo, page, rect.left, rect.top, 249 rect.right, rect.bottom); 250 } 251 } 252 253 void CPDFSDK_FormFillEnvironment::SetCursor(int nCursorType) { 254 if (m_pInfo && m_pInfo->FFI_SetCursor) 255 m_pInfo->FFI_SetCursor(m_pInfo, nCursorType); 256 } 257 258 int CPDFSDK_FormFillEnvironment::SetTimer(int uElapse, 259 TimerCallback lpTimerFunc) { 260 if (m_pInfo && m_pInfo->FFI_SetTimer) 261 return m_pInfo->FFI_SetTimer(m_pInfo, uElapse, lpTimerFunc); 262 return -1; 263 } 264 265 void CPDFSDK_FormFillEnvironment::KillTimer(int nTimerID) { 266 if (m_pInfo && m_pInfo->FFI_KillTimer) 267 m_pInfo->FFI_KillTimer(m_pInfo, nTimerID); 268 } 269 270 FX_SYSTEMTIME CPDFSDK_FormFillEnvironment::GetLocalTime() const { 271 FX_SYSTEMTIME fxtime; 272 if (!m_pInfo || !m_pInfo->FFI_GetLocalTime) 273 return fxtime; 274 275 FPDF_SYSTEMTIME systime = m_pInfo->FFI_GetLocalTime(m_pInfo); 276 fxtime.wDay = systime.wDay; 277 fxtime.wDayOfWeek = systime.wDayOfWeek; 278 fxtime.wHour = systime.wHour; 279 fxtime.wMilliseconds = systime.wMilliseconds; 280 fxtime.wMinute = systime.wMinute; 281 fxtime.wMonth = systime.wMonth; 282 fxtime.wSecond = systime.wSecond; 283 fxtime.wYear = systime.wYear; 284 return fxtime; 285 } 286 287 void CPDFSDK_FormFillEnvironment::OnChange() { 288 if (m_pInfo && m_pInfo->FFI_OnChange) 289 m_pInfo->FFI_OnChange(m_pInfo); 290 } 291 292 FPDF_PAGE CPDFSDK_FormFillEnvironment::GetCurrentPage( 293 UnderlyingDocumentType* document) { 294 if (m_pInfo && m_pInfo->FFI_GetCurrentPage) 295 return m_pInfo->FFI_GetCurrentPage(m_pInfo, document); 296 return nullptr; 297 } 298 299 void CPDFSDK_FormFillEnvironment::ExecuteNamedAction(const char* namedAction) { 300 if (m_pInfo && m_pInfo->FFI_ExecuteNamedAction) 301 m_pInfo->FFI_ExecuteNamedAction(m_pInfo, namedAction); 302 } 303 304 void CPDFSDK_FormFillEnvironment::OnSetFieldInputFocus( 305 FPDF_WIDESTRING focusText, 306 FPDF_DWORD nTextLen, 307 bool bFocus) { 308 if (m_pInfo && m_pInfo->FFI_SetTextFieldFocus) 309 m_pInfo->FFI_SetTextFieldFocus(m_pInfo, focusText, nTextLen, bFocus); 310 } 311 312 void CPDFSDK_FormFillEnvironment::DoURIAction(const char* bsURI) { 313 if (m_pInfo && m_pInfo->FFI_DoURIAction) 314 m_pInfo->FFI_DoURIAction(m_pInfo, bsURI); 315 } 316 317 void CPDFSDK_FormFillEnvironment::DoGoToAction(int nPageIndex, 318 int zoomMode, 319 float* fPosArray, 320 int sizeOfArray) { 321 if (m_pInfo && m_pInfo->FFI_DoGoToAction) { 322 m_pInfo->FFI_DoGoToAction(m_pInfo, nPageIndex, zoomMode, fPosArray, 323 sizeOfArray); 324 } 325 } 326 327 #ifdef PDF_ENABLE_XFA 328 void CPDFSDK_FormFillEnvironment::DisplayCaret(CPDFXFA_Page* page, 329 FPDF_BOOL bVisible, 330 double left, 331 double top, 332 double right, 333 double bottom) { 334 if (m_pInfo && m_pInfo->FFI_DisplayCaret) { 335 m_pInfo->FFI_DisplayCaret(m_pInfo, page, bVisible, left, top, right, 336 bottom); 337 } 338 } 339 340 int CPDFSDK_FormFillEnvironment::GetCurrentPageIndex( 341 CPDFXFA_Context* document) { 342 if (!m_pInfo || !m_pInfo->FFI_GetCurrentPageIndex) 343 return -1; 344 return m_pInfo->FFI_GetCurrentPageIndex(m_pInfo, document); 345 } 346 347 void CPDFSDK_FormFillEnvironment::SetCurrentPage(CPDFXFA_Context* document, 348 int iCurPage) { 349 if (m_pInfo && m_pInfo->FFI_SetCurrentPage) 350 m_pInfo->FFI_SetCurrentPage(m_pInfo, document, iCurPage); 351 } 352 353 WideString CPDFSDK_FormFillEnvironment::GetPlatform() { 354 if (!m_pInfo || !m_pInfo->FFI_GetPlatform) 355 return WideString(); 356 357 int nRequiredLen = m_pInfo->FFI_GetPlatform(m_pInfo, nullptr, 0); 358 if (nRequiredLen <= 0) 359 return WideString(); 360 361 std::vector<uint8_t> pBuff(nRequiredLen); 362 int nActualLen = 363 m_pInfo->FFI_GetPlatform(m_pInfo, pBuff.data(), nRequiredLen); 364 if (nActualLen <= 0 || nActualLen > nRequiredLen) 365 return WideString(); 366 367 return WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()), 368 nActualLen / sizeof(uint16_t)); 369 } 370 371 void CPDFSDK_FormFillEnvironment::GotoURL(CPDFXFA_Context* document, 372 const WideStringView& wsURL) { 373 if (!m_pInfo || !m_pInfo->FFI_GotoURL) 374 return; 375 376 ByteString bsTo = WideString(wsURL).UTF16LE_Encode(); 377 FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(wsURL.GetLength()); 378 m_pInfo->FFI_GotoURL(m_pInfo, document, pTo); 379 bsTo.ReleaseBuffer(bsTo.GetStringLength()); 380 } 381 382 void CPDFSDK_FormFillEnvironment::GetPageViewRect(CPDFXFA_Page* page, 383 FS_RECTF& dstRect) { 384 if (!m_pInfo || !m_pInfo->FFI_GetPageViewRect) 385 return; 386 387 double left; 388 double top; 389 double right; 390 double bottom; 391 m_pInfo->FFI_GetPageViewRect(m_pInfo, page, &left, &top, &right, &bottom); 392 if (top < bottom) 393 std::swap(top, bottom); 394 395 dstRect.left = static_cast<float>(left); 396 dstRect.top = static_cast<float>(top); 397 dstRect.bottom = static_cast<float>(bottom); 398 dstRect.right = static_cast<float>(right); 399 } 400 401 bool CPDFSDK_FormFillEnvironment::PopupMenu(CPDFXFA_Page* page, 402 FPDF_WIDGET hWidget, 403 int menuFlag, 404 CFX_PointF pt) { 405 return m_pInfo && m_pInfo->FFI_PopupMenu && 406 m_pInfo->FFI_PopupMenu(m_pInfo, page, hWidget, menuFlag, pt.x, pt.y); 407 } 408 409 void CPDFSDK_FormFillEnvironment::Alert(FPDF_WIDESTRING Msg, 410 FPDF_WIDESTRING Title, 411 int Type, 412 int Icon) { 413 if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_alert) { 414 m_pInfo->m_pJsPlatform->app_alert(m_pInfo->m_pJsPlatform, Msg, Title, Type, 415 Icon); 416 } 417 } 418 419 void CPDFSDK_FormFillEnvironment::EmailTo(FPDF_FILEHANDLER* fileHandler, 420 FPDF_WIDESTRING pTo, 421 FPDF_WIDESTRING pSubject, 422 FPDF_WIDESTRING pCC, 423 FPDF_WIDESTRING pBcc, 424 FPDF_WIDESTRING pMsg) { 425 if (m_pInfo && m_pInfo->FFI_EmailTo) 426 m_pInfo->FFI_EmailTo(m_pInfo, fileHandler, pTo, pSubject, pCC, pBcc, pMsg); 427 } 428 429 void CPDFSDK_FormFillEnvironment::UploadTo(FPDF_FILEHANDLER* fileHandler, 430 int fileFlag, 431 FPDF_WIDESTRING uploadTo) { 432 if (m_pInfo && m_pInfo->FFI_UploadTo) 433 m_pInfo->FFI_UploadTo(m_pInfo, fileHandler, fileFlag, uploadTo); 434 } 435 436 FPDF_FILEHANDLER* CPDFSDK_FormFillEnvironment::OpenFile(int fileType, 437 FPDF_WIDESTRING wsURL, 438 const char* mode) { 439 if (m_pInfo && m_pInfo->FFI_OpenFile) 440 return m_pInfo->FFI_OpenFile(m_pInfo, fileType, wsURL, mode); 441 return nullptr; 442 } 443 444 RetainPtr<IFX_SeekableReadStream> CPDFSDK_FormFillEnvironment::DownloadFromURL( 445 const wchar_t* url) { 446 if (!m_pInfo || !m_pInfo->FFI_DownloadFromURL) 447 return nullptr; 448 449 ByteString bstrURL = WideString(url).UTF16LE_Encode(); 450 FPDF_WIDESTRING wsURL = 451 (FPDF_WIDESTRING)bstrURL.GetBuffer(bstrURL.GetLength()); 452 453 FPDF_LPFILEHANDLER fileHandler = m_pInfo->FFI_DownloadFromURL(m_pInfo, wsURL); 454 return MakeSeekableStream(fileHandler); 455 } 456 457 WideString CPDFSDK_FormFillEnvironment::PostRequestURL( 458 const wchar_t* wsURL, 459 const wchar_t* wsData, 460 const wchar_t* wsContentType, 461 const wchar_t* wsEncode, 462 const wchar_t* wsHeader) { 463 if (!m_pInfo || !m_pInfo->FFI_PostRequestURL) 464 return L""; 465 466 ByteString bsURL = WideString(wsURL).UTF16LE_Encode(); 467 FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength()); 468 469 ByteString bsData = WideString(wsData).UTF16LE_Encode(); 470 FPDF_WIDESTRING data = (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength()); 471 472 ByteString bsContentType = WideString(wsContentType).UTF16LE_Encode(); 473 FPDF_WIDESTRING contentType = 474 (FPDF_WIDESTRING)bsContentType.GetBuffer(bsContentType.GetLength()); 475 476 ByteString bsEncode = WideString(wsEncode).UTF16LE_Encode(); 477 FPDF_WIDESTRING encode = 478 (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength()); 479 480 ByteString bsHeader = WideString(wsHeader).UTF16LE_Encode(); 481 FPDF_WIDESTRING header = 482 (FPDF_WIDESTRING)bsHeader.GetBuffer(bsHeader.GetLength()); 483 484 FPDF_BSTR response; 485 FPDF_BStr_Init(&response); 486 m_pInfo->FFI_PostRequestURL(m_pInfo, URL, data, contentType, encode, header, 487 &response); 488 489 WideString wsRet = WideString::FromUTF16LE( 490 (FPDF_WIDESTRING)response.str, response.len / sizeof(FPDF_WIDESTRING)); 491 FPDF_BStr_Clear(&response); 492 493 return wsRet; 494 } 495 496 FPDF_BOOL CPDFSDK_FormFillEnvironment::PutRequestURL(const wchar_t* wsURL, 497 const wchar_t* wsData, 498 const wchar_t* wsEncode) { 499 if (!m_pInfo || !m_pInfo->FFI_PutRequestURL) 500 return false; 501 502 ByteString bsURL = WideString(wsURL).UTF16LE_Encode(); 503 FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength()); 504 505 ByteString bsData = WideString(wsData).UTF16LE_Encode(); 506 FPDF_WIDESTRING data = (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength()); 507 508 ByteString bsEncode = WideString(wsEncode).UTF16LE_Encode(); 509 FPDF_WIDESTRING encode = 510 (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength()); 511 512 return m_pInfo->FFI_PutRequestURL(m_pInfo, URL, data, encode); 513 } 514 515 WideString CPDFSDK_FormFillEnvironment::GetLanguage() { 516 if (!m_pInfo || !m_pInfo->FFI_GetLanguage) 517 return WideString(); 518 519 int nRequiredLen = m_pInfo->FFI_GetLanguage(m_pInfo, nullptr, 0); 520 if (nRequiredLen <= 0) 521 return WideString(); 522 523 std::vector<uint8_t> pBuff(nRequiredLen); 524 int nActualLen = 525 m_pInfo->FFI_GetLanguage(m_pInfo, pBuff.data(), nRequiredLen); 526 if (nActualLen <= 0 || nActualLen > nRequiredLen) 527 return WideString(); 528 529 return WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()), 530 nActualLen / sizeof(uint16_t)); 531 } 532 533 void CPDFSDK_FormFillEnvironment::PageEvent(int iPageCount, 534 uint32_t dwEventType) const { 535 if (m_pInfo && m_pInfo->FFI_PageEvent) 536 m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType); 537 } 538 #endif // PDF_ENABLE_XFA 539 540 void CPDFSDK_FormFillEnvironment::ClearAllFocusedAnnots() { 541 for (auto& it : m_PageMap) { 542 if (it.second->IsValidSDKAnnot(GetFocusAnnot())) 543 KillFocusAnnot(0); 544 } 545 } 546 547 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView( 548 UnderlyingPageType* pUnderlyingPage, 549 bool renew) { 550 auto it = m_PageMap.find(pUnderlyingPage); 551 if (it != m_PageMap.end()) 552 return it->second.get(); 553 554 if (!renew) 555 return nullptr; 556 557 auto pNew = pdfium::MakeUnique<CPDFSDK_PageView>(this, pUnderlyingPage); 558 CPDFSDK_PageView* pPageView = pNew.get(); 559 m_PageMap[pUnderlyingPage] = std::move(pNew); 560 561 // Delay to load all the annotations, to avoid endless loop. 562 pPageView->LoadFXAnnots(); 563 return pPageView; 564 } 565 566 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetCurrentView() { 567 UnderlyingPageType* pPage = 568 UnderlyingFromFPDFPage(GetCurrentPage(m_pUnderlyingDoc.Get())); 569 return pPage ? GetPageView(pPage, true) : nullptr; 570 } 571 572 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(int nIndex) { 573 UnderlyingPageType* pTempPage = GetPage(nIndex); 574 if (!pTempPage) 575 return nullptr; 576 577 auto it = m_PageMap.find(pTempPage); 578 return it != m_PageMap.end() ? it->second.get() : nullptr; 579 } 580 581 void CPDFSDK_FormFillEnvironment::ProcJavascriptFun() { 582 CPDF_Document* pPDFDoc = GetPDFDocument(); 583 CPDF_DocJSActions docJS(pPDFDoc); 584 int iCount = docJS.CountJSActions(); 585 for (int i = 0; i < iCount; i++) { 586 WideString csJSName; 587 CPDF_Action jsAction = docJS.GetJSActionAndName(i, &csJSName); 588 GetActionHandler()->DoAction_JavaScript(jsAction, csJSName, this); 589 } 590 } 591 592 bool CPDFSDK_FormFillEnvironment::ProcOpenAction() { 593 if (!m_pUnderlyingDoc) 594 return false; 595 596 const CPDF_Dictionary* pRoot = GetPDFDocument()->GetRoot(); 597 if (!pRoot) 598 return false; 599 600 CPDF_Object* pOpenAction = pRoot->GetDictFor("OpenAction"); 601 if (!pOpenAction) 602 pOpenAction = pRoot->GetArrayFor("OpenAction"); 603 if (!pOpenAction) 604 return false; 605 606 if (pOpenAction->IsArray()) 607 return true; 608 609 CPDF_Dictionary* pDict = pOpenAction->AsDictionary(); 610 if (!pDict) 611 return false; 612 613 CPDF_Action action(pDict); 614 GetActionHandler()->DoAction_DocOpen(action, this); 615 return true; 616 } 617 618 void CPDFSDK_FormFillEnvironment::RemovePageView( 619 UnderlyingPageType* pUnderlyingPage) { 620 auto it = m_PageMap.find(pUnderlyingPage); 621 if (it == m_PageMap.end()) 622 return; 623 624 CPDFSDK_PageView* pPageView = it->second.get(); 625 if (pPageView->IsLocked() || pPageView->IsBeingDestroyed()) 626 return; 627 628 // Mark the page view so we do not come into |RemovePageView| a second 629 // time while we're in the process of removing. 630 pPageView->SetBeingDestroyed(); 631 632 // This must happen before we remove |pPageView| from the map because 633 // |KillFocusAnnot| can call into the |GetPage| method which will 634 // look for this page view in the map, if it doesn't find it a new one will 635 // be created. We then have two page views pointing to the same page and 636 // bad things happen. 637 if (pPageView->IsValidSDKAnnot(GetFocusAnnot())) 638 KillFocusAnnot(0); 639 640 // Remove the page from the map to make sure we don't accidentally attempt 641 // to use the |pPageView| while we're cleaning it up. 642 m_PageMap.erase(it); 643 } 644 645 UnderlyingPageType* CPDFSDK_FormFillEnvironment::GetPage(int nIndex) { 646 if (!m_pInfo || !m_pInfo->FFI_GetPage) 647 return nullptr; 648 return UnderlyingFromFPDFPage( 649 m_pInfo->FFI_GetPage(m_pInfo, m_pUnderlyingDoc.Get(), nIndex)); 650 } 651 652 CPDFSDK_InterForm* CPDFSDK_FormFillEnvironment::GetInterForm() { 653 if (!m_pInterForm) 654 m_pInterForm = pdfium::MakeUnique<CPDFSDK_InterForm>(this); 655 return m_pInterForm.get(); 656 } 657 658 void CPDFSDK_FormFillEnvironment::UpdateAllViews(CPDFSDK_PageView* pSender, 659 CPDFSDK_Annot* pAnnot) { 660 for (const auto& it : m_PageMap) { 661 CPDFSDK_PageView* pPageView = it.second.get(); 662 if (pPageView != pSender) 663 pPageView->UpdateView(pAnnot); 664 } 665 } 666 667 bool CPDFSDK_FormFillEnvironment::SetFocusAnnot( 668 CPDFSDK_Annot::ObservedPtr* pAnnot) { 669 if (m_bBeingDestroyed) 670 return false; 671 if (m_pFocusAnnot == *pAnnot) 672 return true; 673 if (m_pFocusAnnot && !KillFocusAnnot(0)) 674 return false; 675 if (!*pAnnot) 676 return false; 677 678 CPDFSDK_PageView* pPageView = (*pAnnot)->GetPageView(); 679 if (!pPageView || !pPageView->IsValid()) 680 return false; 681 682 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr(); 683 if (m_pFocusAnnot) 684 return false; 685 686 #ifdef PDF_ENABLE_XFA 687 CPDFSDK_Annot::ObservedPtr pLastFocusAnnot(m_pFocusAnnot.Get()); 688 if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot, &pLastFocusAnnot)) 689 return false; 690 #endif // PDF_ENABLE_XFA 691 if (!pAnnotHandler->Annot_OnSetFocus(pAnnot, 0)) 692 return false; 693 if (m_pFocusAnnot) 694 return false; 695 696 m_pFocusAnnot.Reset(pAnnot->Get()); 697 return true; 698 } 699 700 bool CPDFSDK_FormFillEnvironment::KillFocusAnnot(uint32_t nFlag) { 701 if (!m_pFocusAnnot) 702 return false; 703 704 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr(); 705 CPDFSDK_Annot::ObservedPtr pFocusAnnot(m_pFocusAnnot.Get()); 706 m_pFocusAnnot.Reset(); 707 708 #ifdef PDF_ENABLE_XFA 709 CPDFSDK_Annot::ObservedPtr pNull; 710 if (!pAnnotHandler->Annot_OnChangeFocus(&pNull, &pFocusAnnot)) 711 return false; 712 #endif // PDF_ENABLE_XFA 713 714 if (!pAnnotHandler->Annot_OnKillFocus(&pFocusAnnot, nFlag)) { 715 m_pFocusAnnot.Reset(pFocusAnnot.Get()); 716 return false; 717 } 718 719 if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) { 720 CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pFocusAnnot.Get()); 721 FormFieldType fieldType = pWidget->GetFieldType(); 722 if (fieldType == FormFieldType::kTextField || 723 fieldType == FormFieldType::kComboBox) { 724 OnSetFieldInputFocus(nullptr, 0, false); 725 } 726 } 727 return !m_pFocusAnnot; 728 } 729 730 bool CPDFSDK_FormFillEnvironment::GetPermissions(int nFlag) const { 731 return !!(GetPDFDocument()->GetUserPermissions() & nFlag); 732 } 733