OLD | NEW |
---|---|
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "fpdfsdk/fpdfxfa/cpdfxfa_document.h" | 7 #include "fpdfsdk/fpdfxfa/cpdfxfa_document.h" |
8 | 8 |
9 #include "core/fpdfapi/parser/cpdf_document.h" | 9 #include "core/fpdfapi/parser/cpdf_document.h" |
10 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" | 10 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" |
11 #include "fpdfsdk/cpdfsdk_interform.h" | 11 #include "fpdfsdk/cpdfsdk_interform.h" |
12 #include "fpdfsdk/cpdfsdk_pageview.h" | 12 #include "fpdfsdk/cpdfsdk_pageview.h" |
13 #include "fpdfsdk/fpdfxfa/cpdfxfa_app.h" | |
14 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h" | 13 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h" |
15 #include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h" | 14 #include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h" |
16 #include "fpdfsdk/fsdk_define.h" | 15 #include "fpdfsdk/fsdk_define.h" |
16 #include "fpdfsdk/javascript/cjs_runtime.h" | |
17 #include "fpdfsdk/javascript/ijs_runtime.h" | 17 #include "fpdfsdk/javascript/ijs_runtime.h" |
18 #include "public/fpdf_formfill.h" | 18 #include "public/fpdf_formfill.h" |
19 #include "third_party/base/ptr_util.h" | 19 #include "third_party/base/ptr_util.h" |
20 #include "xfa/fxfa/cxfa_eventparam.h" | 20 #include "xfa/fxfa/cxfa_eventparam.h" |
21 #include "xfa/fxfa/xfa_ffapp.h" | 21 #include "xfa/fxfa/xfa_ffapp.h" |
22 #include "xfa/fxfa/xfa_ffdoc.h" | 22 #include "xfa/fxfa/xfa_ffdoc.h" |
23 #include "xfa/fxfa/xfa_ffdocview.h" | 23 #include "xfa/fxfa/xfa_ffdocview.h" |
24 #include "xfa/fxfa/xfa_ffpageview.h" | 24 #include "xfa/fxfa/xfa_ffpageview.h" |
25 #include "xfa/fxfa/xfa_ffwidgethandler.h" | 25 #include "xfa/fxfa/xfa_ffwidgethandler.h" |
26 #include "xfa/fxfa/xfa_fontmgr.h" | |
26 | 27 |
27 #ifndef _WIN32 | 28 #ifndef _WIN32 |
28 extern void SetLastError(int err); | 29 extern void SetLastError(int err); |
29 extern int GetLastError(); | 30 extern int GetLastError(); |
30 #endif | 31 #endif |
31 | 32 |
32 CPDFXFA_Document::CPDFXFA_Document(std::unique_ptr<CPDF_Document> pPDFDoc) | 33 CPDFXFA_Document::CPDFXFA_Document(std::unique_ptr<CPDF_Document> pPDFDoc) |
33 : m_iDocType(DOCTYPE_PDF), | 34 : m_iDocType(DOCTYPE_PDF), |
34 m_pPDFDoc(std::move(pPDFDoc)), | 35 m_pPDFDoc(std::move(pPDFDoc)), |
35 m_pFormFillEnv(nullptr), | 36 m_pFormFillEnv(nullptr), |
36 m_pXFADocView(nullptr), | 37 m_pXFADocView(nullptr), |
37 m_nLoadStatus(FXFA_LOADSTATUS_PRELOAD), | 38 m_nLoadStatus(FXFA_LOADSTATUS_PRELOAD), |
38 m_nPageCount(0), | 39 m_nPageCount(0), |
39 m_DocEnv(this) {} | 40 m_DocEnv(this) { |
41 m_pXFAApp = pdfium::MakeUnique<CXFA_FFApp>(this); | |
42 m_pXFAApp->SetDefaultFontMgr(pdfium::MakeUnique<CXFA_DefFontMgr>()); | |
43 } | |
40 | 44 |
41 CPDFXFA_Document::~CPDFXFA_Document() { | 45 CPDFXFA_Document::~CPDFXFA_Document() { |
42 m_nLoadStatus = FXFA_LOADSTATUS_CLOSING; | 46 m_nLoadStatus = FXFA_LOADSTATUS_CLOSING; |
43 | 47 |
44 // Must happen before we remove the form fill environment. | 48 // Must happen before we remove the form fill environment. |
45 if (m_pXFADoc) { | 49 if (m_pXFADoc) |
46 if (CXFA_FFApp* pApp = GetApp()->GetXFAApp()) | 50 CloseXFADoc(); |
Tom Sepez
2016/11/02 19:19:34
Maybe CloseXFADoc() should make this check itself
dsinclair
2016/11/02 19:22:34
Done.
| |
47 CloseXFADoc(pApp->GetDocHandler()); | |
48 } | |
49 | 51 |
50 if (m_pFormFillEnv) { | 52 if (m_pFormFillEnv) { |
51 m_pFormFillEnv->ClearAllFocusedAnnots(); | 53 m_pFormFillEnv->ClearAllFocusedAnnots(); |
52 // Once we're deleted the FormFillEnvironment will point at a bad underlying | 54 // Once we're deleted the FormFillEnvironment will point at a bad underlying |
53 // doc so we need to reset it ... | 55 // doc so we need to reset it ... |
54 m_pFormFillEnv->ResetXFADocument(); | 56 m_pFormFillEnv->ResetXFADocument(); |
55 m_pFormFillEnv = nullptr; | 57 m_pFormFillEnv = nullptr; |
56 } | 58 } |
57 | 59 |
58 m_nLoadStatus = FXFA_LOADSTATUS_CLOSED; | 60 m_nLoadStatus = FXFA_LOADSTATUS_CLOSED; |
59 } | 61 } |
60 | 62 |
61 void CPDFXFA_Document::CloseXFADoc(CXFA_FFDocHandler* pDoc) { | 63 void CPDFXFA_Document::CloseXFADoc() { |
62 if (!pDoc) | |
63 return; | |
64 m_pXFADoc->CloseDoc(); | 64 m_pXFADoc->CloseDoc(); |
65 m_pXFADoc.reset(); | 65 m_pXFADoc.reset(); |
66 m_pXFADocView = nullptr; | 66 m_pXFADocView = nullptr; |
67 } | 67 } |
68 | 68 |
69 CPDFXFA_App* CPDFXFA_Document::GetApp() { | |
70 if (!m_pApp) | |
71 m_pApp = pdfium::MakeUnique<CPDFXFA_App>(); | |
72 return m_pApp.get(); | |
73 } | |
74 | |
75 void CPDFXFA_Document::SetFormFillEnv( | 69 void CPDFXFA_Document::SetFormFillEnv( |
76 CPDFSDK_FormFillEnvironment* pFormFillEnv) { | 70 CPDFSDK_FormFillEnvironment* pFormFillEnv) { |
77 // The layout data can have pointers back into the script context. That | 71 // The layout data can have pointers back into the script context. That |
78 // context will be different if the form fill environment closes, so, force | 72 // context will be different if the form fill environment closes, so, force |
79 // the layout data to clear. | 73 // the layout data to clear. |
80 if (m_pXFADoc && m_pXFADoc->GetXFADoc()) | 74 if (m_pXFADoc && m_pXFADoc->GetXFADoc()) |
81 m_pXFADoc->GetXFADoc()->ClearLayoutData(); | 75 m_pXFADoc->GetXFADoc()->ClearLayoutData(); |
82 | 76 |
83 GetApp()->SetFormFillEnv(pFormFillEnv); | |
84 m_pFormFillEnv = pFormFillEnv; | 77 m_pFormFillEnv = pFormFillEnv; |
85 } | 78 } |
86 | 79 |
87 FX_BOOL CPDFXFA_Document::LoadXFADoc() { | 80 FX_BOOL CPDFXFA_Document::LoadXFADoc() { |
88 m_nLoadStatus = FXFA_LOADSTATUS_LOADING; | 81 m_nLoadStatus = FXFA_LOADSTATUS_LOADING; |
89 | 82 |
90 if (!m_pPDFDoc) | 83 if (!m_pPDFDoc) |
91 return FALSE; | 84 return FALSE; |
92 | 85 |
93 m_XFAPageList.RemoveAll(); | 86 m_XFAPageList.RemoveAll(); |
94 | 87 |
95 CXFA_FFApp* pApp = GetApp()->GetXFAApp(); | 88 CXFA_FFApp* pApp = GetXFAApp(); |
96 if (!pApp) | 89 if (!pApp) |
97 return FALSE; | 90 return FALSE; |
98 | 91 |
99 m_pXFADoc.reset(pApp->CreateDoc(&m_DocEnv, m_pPDFDoc.get())); | 92 m_pXFADoc.reset(pApp->CreateDoc(&m_DocEnv, m_pPDFDoc.get())); |
100 if (!m_pXFADoc) { | 93 if (!m_pXFADoc) { |
101 SetLastError(FPDF_ERR_XFALOAD); | 94 SetLastError(FPDF_ERR_XFALOAD); |
102 return FALSE; | 95 return FALSE; |
103 } | 96 } |
104 | 97 |
105 CXFA_FFDocHandler* pDocHandler = pApp->GetDocHandler(); | 98 CXFA_FFDocHandler* pDocHandler = pApp->GetDocHandler(); |
106 if (!pDocHandler) { | 99 if (!pDocHandler) { |
107 SetLastError(FPDF_ERR_XFALOAD); | 100 SetLastError(FPDF_ERR_XFALOAD); |
108 return FALSE; | 101 return FALSE; |
109 } | 102 } |
110 | 103 |
111 m_pXFADoc->StartLoad(); | 104 m_pXFADoc->StartLoad(); |
112 int iStatus = m_pXFADoc->DoLoad(nullptr); | 105 int iStatus = m_pXFADoc->DoLoad(nullptr); |
113 if (iStatus != XFA_PARSESTATUS_Done) { | 106 if (iStatus != XFA_PARSESTATUS_Done) { |
114 CloseXFADoc(pDocHandler); | 107 CloseXFADoc(); |
115 SetLastError(FPDF_ERR_XFALOAD); | 108 SetLastError(FPDF_ERR_XFALOAD); |
116 return FALSE; | 109 return FALSE; |
117 } | 110 } |
118 m_pXFADoc->StopLoad(); | 111 m_pXFADoc->StopLoad(); |
119 m_pXFADoc->GetXFADoc()->InitScriptContext(GetApp()->GetJSERuntime()); | 112 m_pXFADoc->GetXFADoc()->InitScriptContext(GetJSERuntime()); |
120 | 113 |
121 if (m_pXFADoc->GetDocType() == XFA_DOCTYPE_Dynamic) | 114 if (m_pXFADoc->GetDocType() == XFA_DOCTYPE_Dynamic) |
122 m_iDocType = DOCTYPE_DYNAMIC_XFA; | 115 m_iDocType = DOCTYPE_DYNAMIC_XFA; |
123 else | 116 else |
124 m_iDocType = DOCTYPE_STATIC_XFA; | 117 m_iDocType = DOCTYPE_STATIC_XFA; |
125 | 118 |
126 m_pXFADocView = m_pXFADoc->CreateDocView(XFA_DOCVIEW_View); | 119 m_pXFADocView = m_pXFADoc->CreateDocView(XFA_DOCVIEW_View); |
127 if (m_pXFADocView->StartLayout() < 0) { | 120 if (m_pXFADocView->StartLayout() < 0) { |
128 CloseXFADoc(pDocHandler); | 121 CloseXFADoc(); |
129 SetLastError(FPDF_ERR_XFALAYOUT); | 122 SetLastError(FPDF_ERR_XFALAYOUT); |
130 return FALSE; | 123 return FALSE; |
131 } | 124 } |
132 | 125 |
133 m_pXFADocView->DoLayout(nullptr); | 126 m_pXFADocView->DoLayout(nullptr); |
134 m_pXFADocView->StopLayout(); | 127 m_pXFADocView->StopLayout(); |
135 m_nLoadStatus = FXFA_LOADSTATUS_LOADED; | 128 m_nLoadStatus = FXFA_LOADSTATUS_LOADED; |
136 | 129 |
137 return TRUE; | 130 return TRUE; |
138 } | 131 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 } | 210 } |
218 | 211 |
219 void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) { | 212 void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) { |
220 m_XFAPageList.SetAt(page->GetPageIndex(), nullptr); | 213 m_XFAPageList.SetAt(page->GetPageIndex(), nullptr); |
221 } | 214 } |
222 | 215 |
223 void CPDFXFA_Document::ClearChangeMark() { | 216 void CPDFXFA_Document::ClearChangeMark() { |
224 if (m_pFormFillEnv) | 217 if (m_pFormFillEnv) |
225 m_pFormFillEnv->ClearChangeMark(); | 218 m_pFormFillEnv->ClearChangeMark(); |
226 } | 219 } |
220 | |
221 v8::Isolate* CPDFXFA_Document::GetJSERuntime() const { | |
222 if (!m_pFormFillEnv) | |
223 return nullptr; | |
224 | |
225 // XFA requires V8, if we have V8 then we have a CJS_Runtime and not the stub. | |
226 CJS_Runtime* runtime = | |
227 static_cast<CJS_Runtime*>(m_pFormFillEnv->GetJSRuntime()); | |
228 return runtime->GetIsolate(); | |
229 } | |
230 | |
231 void CPDFXFA_Document::GetAppName(CFX_WideString& wsName) { | |
232 if (m_pFormFillEnv) | |
233 wsName = m_pFormFillEnv->FFI_GetAppName(); | |
234 } | |
235 | |
236 void CPDFXFA_Document::GetLanguage(CFX_WideString& wsLanguage) { | |
237 if (m_pFormFillEnv) | |
238 wsLanguage = m_pFormFillEnv->GetLanguage(); | |
239 } | |
240 | |
241 void CPDFXFA_Document::GetPlatform(CFX_WideString& wsPlatform) { | |
242 if (m_pFormFillEnv) | |
243 wsPlatform = m_pFormFillEnv->GetPlatform(); | |
244 } | |
245 | |
246 void CPDFXFA_Document::Beep(uint32_t dwType) { | |
247 if (m_pFormFillEnv) | |
248 m_pFormFillEnv->JS_appBeep(dwType); | |
249 } | |
250 | |
251 int32_t CPDFXFA_Document::MsgBox(const CFX_WideString& wsMessage, | |
252 const CFX_WideString& wsTitle, | |
253 uint32_t dwIconType, | |
254 uint32_t dwButtonType) { | |
255 if (!m_pFormFillEnv) | |
256 return -1; | |
257 | |
258 uint32_t iconType = 0; | |
259 int iButtonType = 0; | |
260 switch (dwIconType) { | |
261 case XFA_MBICON_Error: | |
262 iconType |= 0; | |
263 break; | |
264 case XFA_MBICON_Warning: | |
265 iconType |= 1; | |
266 break; | |
267 case XFA_MBICON_Question: | |
268 iconType |= 2; | |
269 break; | |
270 case XFA_MBICON_Status: | |
271 iconType |= 3; | |
272 break; | |
273 } | |
274 switch (dwButtonType) { | |
275 case XFA_MB_OK: | |
276 iButtonType |= 0; | |
277 break; | |
278 case XFA_MB_OKCancel: | |
279 iButtonType |= 1; | |
280 break; | |
281 case XFA_MB_YesNo: | |
282 iButtonType |= 2; | |
283 break; | |
284 case XFA_MB_YesNoCancel: | |
285 iButtonType |= 3; | |
286 break; | |
287 } | |
288 int32_t iRet = m_pFormFillEnv->JS_appAlert(wsMessage.c_str(), wsTitle.c_str(), | |
289 iButtonType, iconType); | |
290 switch (iRet) { | |
291 case 1: | |
292 return XFA_IDOK; | |
293 case 2: | |
294 return XFA_IDCancel; | |
295 case 3: | |
296 return XFA_IDNo; | |
297 case 4: | |
298 return XFA_IDYes; | |
299 } | |
300 return XFA_IDYes; | |
301 } | |
302 | |
303 CFX_WideString CPDFXFA_Document::Response(const CFX_WideString& wsQuestion, | |
304 const CFX_WideString& wsTitle, | |
305 const CFX_WideString& wsDefaultAnswer, | |
306 FX_BOOL bMark) { | |
307 CFX_WideString wsAnswer; | |
308 if (!m_pFormFillEnv) | |
309 return wsAnswer; | |
310 | |
311 int nLength = 2048; | |
312 char* pBuff = new char[nLength]; | |
313 nLength = m_pFormFillEnv->JS_appResponse(wsQuestion.c_str(), wsTitle.c_str(), | |
314 wsDefaultAnswer.c_str(), nullptr, | |
315 bMark, pBuff, nLength); | |
316 if (nLength > 0) { | |
317 nLength = nLength > 2046 ? 2046 : nLength; | |
318 pBuff[nLength] = 0; | |
319 pBuff[nLength + 1] = 0; | |
320 wsAnswer = CFX_WideString::FromUTF16LE( | |
321 reinterpret_cast<const unsigned short*>(pBuff), | |
322 nLength / sizeof(unsigned short)); | |
323 } | |
324 delete[] pBuff; | |
325 return wsAnswer; | |
326 } | |
327 | |
328 IFX_SeekableReadStream* CPDFXFA_Document::DownloadURL( | |
329 const CFX_WideString& wsURL) { | |
330 return m_pFormFillEnv ? m_pFormFillEnv->DownloadFromURL(wsURL.c_str()) | |
331 : nullptr; | |
332 } | |
333 | |
334 FX_BOOL CPDFXFA_Document::PostRequestURL(const CFX_WideString& wsURL, | |
335 const CFX_WideString& wsData, | |
336 const CFX_WideString& wsContentType, | |
337 const CFX_WideString& wsEncode, | |
338 const CFX_WideString& wsHeader, | |
339 CFX_WideString& wsResponse) { | |
340 if (!m_pFormFillEnv) | |
341 return FALSE; | |
342 | |
343 wsResponse = m_pFormFillEnv->PostRequestURL( | |
344 wsURL.c_str(), wsData.c_str(), wsContentType.c_str(), wsEncode.c_str(), | |
345 wsHeader.c_str()); | |
346 return TRUE; | |
347 } | |
348 | |
349 FX_BOOL CPDFXFA_Document::PutRequestURL(const CFX_WideString& wsURL, | |
350 const CFX_WideString& wsData, | |
351 const CFX_WideString& wsEncode) { | |
352 return m_pFormFillEnv && | |
353 m_pFormFillEnv->PutRequestURL(wsURL.c_str(), wsData.c_str(), | |
354 wsEncode.c_str()); | |
355 } | |
356 | |
357 void CPDFXFA_Document::LoadString(int32_t iStringID, CFX_WideString& wsString) { | |
358 switch (iStringID) { | |
359 case XFA_IDS_ValidateFailed: | |
360 wsString = L"%s validation failed"; | |
361 return; | |
362 case XFA_IDS_CalcOverride: | |
363 wsString = L"Calculate Override"; | |
364 return; | |
365 case XFA_IDS_ModifyField: | |
366 wsString = L"Are you sure you want to modify this field?"; | |
367 return; | |
368 case XFA_IDS_NotModifyField: | |
369 wsString = L"You are not allowed to modify this field."; | |
370 return; | |
371 case XFA_IDS_AppName: | |
372 wsString = L"pdfium"; | |
373 return; | |
374 case XFA_IDS_Unable_TO_SET: | |
375 wsString = L"Unable to set "; | |
376 return; | |
377 case XFA_IDS_INVAlID_PROP_SET: | |
378 wsString = L"Invalid property set operation."; | |
379 return; | |
380 case XFA_IDS_NOT_DEFAUL_VALUE: | |
381 wsString = L" doesn't have a default property."; | |
382 return; | |
383 case XFA_IDS_UNABLE_SET_LANGUAGE: | |
384 wsString = L"Unable to set language value."; | |
385 return; | |
386 case XFA_IDS_UNABLE_SET_NUMPAGES: | |
387 wsString = L"Unable to set numPages value."; | |
388 return; | |
389 case XFA_IDS_UNABLE_SET_PLATFORM: | |
390 wsString = L"Unable to set platform value."; | |
391 return; | |
392 case XFA_IDS_UNABLE_SET_VARIATION: | |
393 wsString = L"Unable to set variation value."; | |
394 return; | |
395 case XFA_IDS_UNABLE_SET_VERSION: | |
396 wsString = L"Unable to set version value."; | |
397 return; | |
398 case XFA_IDS_UNABLE_SET_READY: | |
399 wsString = L"Unable to set ready value."; | |
400 return; | |
401 case XFA_IDS_COMPILER_ERROR: | |
402 wsString = L"Compiler error."; | |
403 return; | |
404 case XFA_IDS_DIVIDE_ZERO: | |
405 wsString = L"Divide by zero."; | |
406 return; | |
407 case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT: | |
408 wsString = | |
409 L"An attempt was made to reference property '%s' of a non-object in " | |
410 L"SOM expression %s."; | |
411 return; | |
412 case XFA_IDS_INDEX_OUT_OF_BOUNDS: | |
413 wsString = L"Index value is out of bounds."; | |
414 return; | |
415 case XFA_IDS_INCORRECT_NUMBER_OF_METHOD: | |
416 wsString = L"Incorrect number of parameters calling method '%s'."; | |
417 return; | |
418 case XFA_IDS_ARGUMENT_MISMATCH: | |
419 wsString = L"Argument mismatch in property or function argument."; | |
420 return; | |
421 case XFA_IDS_NOT_HAVE_PROPERTY: | |
422 wsString = L"'%s' doesn't have property '%s'."; | |
423 return; | |
424 case XFA_IDS_VIOLATE_BOUNDARY: | |
425 wsString = | |
426 L"The element [%s] has violated its allowable number of occurrences."; | |
427 return; | |
428 case XFA_IDS_SERVER_DENY: | |
429 wsString = L"Server does not permit."; | |
430 return; | |
431 case XFA_IDS_ValidateLimit: | |
432 wsString = | |
433 L"Message limit exceeded. Remaining %d validation errors not " | |
434 L"reported."; | |
435 return; | |
436 case XFA_IDS_ValidateNullWarning: | |
437 wsString = | |
438 L"%s cannot be blank. To ignore validations for %s, click Ignore."; | |
439 return; | |
440 case XFA_IDS_ValidateNullError: | |
441 wsString = L"%s cannot be blank."; | |
442 return; | |
443 case XFA_IDS_ValidateWarning: | |
444 wsString = | |
445 L"The value you entered for %s is invalid. To ignore validations for " | |
446 L"%s, click Ignore."; | |
447 return; | |
448 case XFA_IDS_ValidateError: | |
449 wsString = L"The value you entered for %s is invalid."; | |
450 return; | |
451 } | |
452 } | |
453 | |
454 IFWL_AdapterTimerMgr* CPDFXFA_Document::GetTimerMgr() { | |
455 CXFA_FWLAdapterTimerMgr* pAdapter = nullptr; | |
456 if (m_pFormFillEnv) | |
457 pAdapter = new CXFA_FWLAdapterTimerMgr(m_pFormFillEnv); | |
458 return pAdapter; | |
459 } | |
OLD | NEW |