1// Copyright 2014 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/include/fsdk_define.h"
8#include "fpdfsdk/include/fsdk_mgr.h"
9#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
10#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
11#include "fpdfsdk/include/javascript/IJavaScript.h"
12#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
13#include "public/fpdf_formfill.h"
14
15CPDFXFA_App* CPDFXFA_App::g_pApp = NULL;
16
17CPDFXFA_App* CPDFXFA_App::GetInstance() {
18  if (!g_pApp) {
19    g_pApp = new CPDFXFA_App();
20  }
21  return g_pApp;
22}
23
24void CPDFXFA_App::ReleaseInstance() {
25  delete g_pApp;
26  g_pApp = NULL;
27}
28
29CPDFXFA_App::CPDFXFA_App()
30    : m_bJavaScriptInitialized(FALSE),
31      m_pXFAApp(NULL),
32      m_pFontMgr(NULL),
33      m_hJSERuntime(NULL),
34      m_csAppType(JS_STR_VIEWERTYPE_STANDARD) {
35  m_pEnvList.RemoveAll();
36}
37
38CPDFXFA_App::~CPDFXFA_App() {
39  delete m_pFontMgr;
40  m_pFontMgr = NULL;
41
42  delete m_pXFAApp;
43  m_pXFAApp = NULL;
44
45#ifdef PDF_ENABLE_XFA
46  FXJSE_Runtime_Release(m_hJSERuntime);
47  m_hJSERuntime = NULL;
48
49  FXJSE_Finalize();
50  BC_Library_Destory();
51#endif
52}
53
54FX_BOOL CPDFXFA_App::Initialize() {
55#ifdef PDF_ENABLE_XFA
56  BC_Library_Init();
57  FXJSE_Initialize();
58
59  m_hJSERuntime = FXJSE_Runtime_Create();
60  if (!m_hJSERuntime)
61    return FALSE;
62
63  m_pXFAApp = IXFA_App::Create(this);
64  if (!m_pXFAApp)
65    return FALSE;
66
67  m_pFontMgr = IXFA_FontMgr::CreateDefault();
68  if (!m_pFontMgr)
69    return FALSE;
70
71  m_pXFAApp->SetDefaultFontMgr(m_pFontMgr);
72#endif
73  return TRUE;
74}
75
76FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv) {
77  if (!pEnv)
78    return FALSE;
79
80  m_pEnvList.Add(pEnv);
81  return TRUE;
82}
83
84FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv) {
85  if (!pEnv)
86    return FALSE;
87
88  int nFind = m_pEnvList.Find(pEnv);
89  if (nFind != -1) {
90    m_pEnvList.RemoveAt(nFind);
91    return TRUE;
92  }
93
94  return FALSE;
95}
96
97void CPDFXFA_App::GetAppType(CFX_WideString& wsAppType) {
98  wsAppType = m_csAppType;
99}
100
101void CPDFXFA_App::GetAppName(CFX_WideString& wsName) {
102  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
103  if (pEnv) {
104    wsName = pEnv->FFI_GetAppName();
105  }
106}
107
108void CPDFXFA_App::SetAppType(const CFX_WideStringC& wsAppType) {
109  m_csAppType = wsAppType;
110}
111
112void CPDFXFA_App::GetLanguage(CFX_WideString& wsLanguage) {
113  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
114  if (pEnv) {
115    wsLanguage = pEnv->FFI_GetLanguage();
116  }
117}
118
119void CPDFXFA_App::GetPlatform(CFX_WideString& wsPlatform) {
120  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
121  if (pEnv) {
122    wsPlatform = pEnv->FFI_GetPlatform();
123  }
124}
125
126void CPDFXFA_App::GetVariation(CFX_WideString& wsVariation) {
127  wsVariation = JS_STR_VIEWERVARIATION;
128}
129
130void CPDFXFA_App::GetVersion(CFX_WideString& wsVersion) {
131  wsVersion = JS_STR_VIEWERVERSION_XFA;
132}
133
134void CPDFXFA_App::Beep(FX_DWORD dwType) {
135  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
136  if (pEnv) {
137    pEnv->JS_appBeep(dwType);
138  }
139}
140
141int32_t CPDFXFA_App::MsgBox(const CFX_WideStringC& wsMessage,
142                            const CFX_WideStringC& wsTitle,
143                            FX_DWORD dwIconType,
144                            FX_DWORD dwButtonType) {
145  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
146  if (!pEnv)
147    return -1;
148
149  FX_DWORD iconType = 0;
150  int iButtonType = 0;
151  switch (dwIconType) {
152    case XFA_MBICON_Error:
153      iconType |= 0;
154      break;
155    case XFA_MBICON_Warning:
156      iconType |= 1;
157      break;
158    case XFA_MBICON_Question:
159      iconType |= 2;
160      break;
161    case XFA_MBICON_Status:
162      iconType |= 3;
163      break;
164  }
165  switch (dwButtonType) {
166    case XFA_MB_OK:
167      iButtonType |= 0;
168      break;
169    case XFA_MB_OKCancel:
170      iButtonType |= 1;
171      break;
172    case XFA_MB_YesNo:
173      iButtonType |= 2;
174      break;
175    case XFA_MB_YesNoCancel:
176      iButtonType |= 3;
177      break;
178  }
179  int32_t iRet = pEnv->JS_appAlert(wsMessage.GetPtr(), wsTitle.GetPtr(),
180                                   iButtonType, iconType);
181  switch (iRet) {
182    case 1:
183      return XFA_IDOK;
184    case 2:
185      return XFA_IDCancel;
186    case 3:
187      return XFA_IDNo;
188    case 4:
189      return XFA_IDYes;
190  }
191  return XFA_IDYes;
192}
193
194void CPDFXFA_App::Response(CFX_WideString& wsAnswer,
195                           const CFX_WideStringC& wsQuestion,
196                           const CFX_WideStringC& wsTitle,
197                           const CFX_WideStringC& wsDefaultAnswer,
198                           FX_BOOL bMark) {
199  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
200  if (pEnv) {
201    int nLength = 2048;
202    char* pBuff = new char[nLength];
203    nLength = pEnv->JS_appResponse(wsQuestion.GetPtr(), wsTitle.GetPtr(),
204                                   wsDefaultAnswer.GetPtr(), NULL, bMark, pBuff,
205                                   nLength);
206    if (nLength > 0) {
207      nLength = nLength > 2046 ? 2046 : nLength;
208      pBuff[nLength] = 0;
209      pBuff[nLength + 1] = 0;
210      wsAnswer = CFX_WideString::FromUTF16LE(
211          reinterpret_cast<const unsigned short*>(pBuff),
212          nLength / sizeof(unsigned short));
213    }
214    delete[] pBuff;
215  }
216}
217
218int32_t CPDFXFA_App::GetCurDocumentInBatch() {
219  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
220  if (pEnv) {
221    return pEnv->FFI_GetCurDocument();
222  }
223  return 0;
224}
225
226int32_t CPDFXFA_App::GetDocumentCountInBatch() {
227  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
228  if (pEnv) {
229    return pEnv->FFI_GetDocumentCount();
230  }
231
232  return 0;
233}
234
235IFX_FileRead* CPDFXFA_App::DownloadURL(const CFX_WideStringC& wsURL) {
236  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
237  if (pEnv) {
238    return pEnv->FFI_DownloadFromURL(wsURL.GetPtr());
239  }
240  return NULL;
241}
242
243FX_BOOL CPDFXFA_App::PostRequestURL(const CFX_WideStringC& wsURL,
244                                    const CFX_WideStringC& wsData,
245                                    const CFX_WideStringC& wsContentType,
246                                    const CFX_WideStringC& wsEncode,
247                                    const CFX_WideStringC& wsHeader,
248                                    CFX_WideString& wsResponse) {
249  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
250  if (pEnv) {
251    wsResponse = pEnv->FFI_PostRequestURL(wsURL.GetPtr(), wsData.GetPtr(),
252                                          wsContentType.GetPtr(),
253                                          wsEncode.GetPtr(), wsHeader.GetPtr());
254    return TRUE;
255  }
256  return FALSE;
257}
258
259FX_BOOL CPDFXFA_App::PutRequestURL(const CFX_WideStringC& wsURL,
260                                   const CFX_WideStringC& wsData,
261                                   const CFX_WideStringC& wsEncode) {
262  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
263  if (pEnv) {
264    return pEnv->FFI_PutRequestURL(wsURL.GetPtr(), wsData.GetPtr(),
265                                   wsEncode.GetPtr());
266  }
267  return FALSE;
268}
269
270void CPDFXFA_App::LoadString(int32_t iStringID, CFX_WideString& wsString) {
271  switch (iStringID) {
272    case XFA_IDS_ValidateFailed:
273      wsString = L"%s validate failed";
274      return;
275    case XFA_IDS_CalcOverride:
276      wsString = L"Calculate Override";
277      return;
278    case XFA_IDS_ModifyField:
279      wsString = L"Are you sure you want to modify this field?";
280      return;
281    case XFA_IDS_NotModifyField:
282      wsString = L"You are not allowed to modify this field.";
283      return;
284    case XFA_IDS_AppName:
285      wsString = L"Foxit";
286      return;
287    case XFA_IDS_ImageFilter:
288      wsString =
289          L"Image "
290          L"Files(*.bmp;*.jpg;*.png;*.gif;*.tif)|*.bmp;*.jpg;*.png;*.gif;*.tif|"
291          L"All Files(*.*)|*.*||";
292      return;
293    case XFA_IDS_UNKNOW_CATCHED:
294      wsString = L"unknown error is catched!";
295      return;
296    case XFA_IDS_Unable_TO_SET:
297      wsString = L"Unable to set ";
298      return;
299    case XFA_IDS_VALUE_EXCALMATORY:
300      wsString = L" value!";
301      return;
302    case XFA_IDS_INVALID_ENUM_VALUE:
303      wsString = L"Invalid enumerated value: ";
304      return;
305    case XFA_IDS_UNSUPPORT_METHOD:
306      wsString = L"unsupport %s method.";
307      return;
308    case XFA_IDS_UNSUPPORT_PROP:
309      wsString = L"unsupport %s property.";
310      return;
311    case XFA_IDS_INVAlID_PROP_SET:
312      wsString = L"Invalid property set operation;";
313      return;
314    case XFA_IDS_NOT_DEFAUL_VALUE:
315      wsString = L" doesn't have a default property";
316      return;
317    case XFA_IDS_UNABLE_SET_LANGUAGE:
318      wsString = L"Unable to set language value!";
319      return;
320    case XFA_IDS_UNABLE_SET_NUMPAGES:
321      wsString = L"Unable to set numPages value!";
322      return;
323    case XFA_IDS_UNABLE_SET_PLATFORM:
324      wsString = L"Unable to set platform value!";
325      return;
326    case XFA_IDS_UNABLE_SET_VALIDATIONENABLE:
327      wsString = L"Unable to set validationsEnabled value!";
328      return;
329    case XFA_IDS_UNABLE_SET_VARIATION:
330      wsString = L"Unable to set variation value!";
331      return;
332    case XFA_IDS_UNABLE_SET_VERSION:
333      wsString = L"Unable to set version value!";
334      return;
335    case XFA_IDS_UNABLE_SET_READY:
336      wsString = L"Unable to set ready value!";
337      return;
338    case XFA_IDS_NUMBER_OF_OCCUR:
339      wsString =
340          L"The element [%s] has violated its allowable number of occurrences";
341      return;
342    case XFA_IDS_UNABLE_SET_CLASS_NAME:
343      wsString = L"Unable to set className value!";
344      return;
345    case XFA_IDS_UNABLE_SET_LENGTH_VALUE:
346      wsString = L"Unable to set length value!";
347      return;
348    case XFA_IDS_UNSUPPORT_CHAR:
349      wsString = L"unsupported char '%c'";
350      return;
351    case XFA_IDS_BAD_SUFFIX:
352      wsString = L"bad suffix on number";
353      return;
354    case XFA_IDS_EXPECTED_IDENT:
355      wsString = L"expected identifier instead of '%s'";
356      return;
357    case XFA_IDS_EXPECTED_STRING:
358      wsString = L"expected '%s' instead of '%s'";
359      return;
360    case XFA_IDS_INVALIDATE_CHAR:
361      wsString = L"invalidate char '%c'";
362      return;
363    case XFA_IDS_REDEFINITION:
364      wsString = L"'%s' redefinition ";
365      return;
366    case XFA_IDS_INVALIDATE_TOKEN:
367      wsString = L"invalidate token '%s'";
368      return;
369    case XFA_IDS_INVALIDATE_EXPRESSION:
370      wsString = L"invalidate expression '%s'";
371      return;
372    case XFA_IDS_UNDEFINE_IDENTIFIER:
373      wsString = L"undefined identifier '%s'";
374      return;
375    case XFA_IDS_INVALIDATE_LEFTVALUE:
376      wsString = L"invalidate left-value '%s'";
377      return;
378    case XFA_IDS_COMPILER_ERROR:
379      wsString = L"compiler error";
380      return;
381    case XFA_IDS_CANNOT_MODIFY_VALUE:
382      wsString = L"can't modify the '%s' value";
383      return;
384    case XFA_IDS_ERROR_PARAMETERS:
385      wsString = L"function '%s' has not %d parameters";
386      return;
387    case XFA_IDS_EXPECT_ENDIF:
388      wsString = L"expected 'endif' instead of '%s'";
389      return;
390    case XFA_IDS_UNEXPECTED_EXPRESSION:
391      wsString = L"unexpected expression '%s'";
392      return;
393    case XFA_IDS_CONDITION_IS_NULL:
394      wsString = L"condition is null";
395      return;
396    case XFA_IDS_ILLEGALBREAK:
397      wsString = L"illegal break";
398      return;
399    case XFA_IDS_ILLEGALCONTINUE:
400      wsString = L"illegal continue";
401      return;
402    case XFA_IDS_EXPECTED_OPERATOR:
403      wsString = L"expected operator '%s' instead of '%s'";
404      return;
405    case XFA_IDS_DIVIDE_ZERO:
406      wsString = L"divide by zero";
407      return;
408    case XFA_IDS_CANNOT_COVERT_OBJECT:
409      wsString = L"%s.%s can not covert to object";
410      return;
411    case XFA_IDS_NOT_FOUND_CONTAINER:
412      wsString = L"can not found container '%s'";
413      return;
414    case XFA_IDS_NOT_FOUND_PROPERTY:
415      wsString = L"can not found property '%s'";
416      return;
417    case XFA_IDS_NOT_FOUND_METHOD:
418      wsString = L"can not found method '%s'";
419      return;
420    case XFA_IDS_NOT_FOUND_CONST:
421      wsString = L"can not found const '%s'";
422      return;
423    case XFA_IDS_NOT_ASSIGN_OBJECT:
424      wsString = L"can not direct assign value to object";
425      return;
426    case XFA_IDS_IVALIDATE_INSTRUCTION:
427      wsString = L"invalidate instruction";
428      return;
429    case XFA_IDS_EXPECT_NUMBER:
430      wsString = L"expected number instead of '%s'";
431      return;
432    case XFA_IDS_VALIDATE_OUT_ARRAY:
433      wsString = L"validate access index '%s' out of array";
434      return;
435    case XFA_IDS_CANNOT_ASSIGN_IDENT:
436      wsString = L"can not assign to %s";
437      return;
438    case XFA_IDS_NOT_FOUNT_FUNCTION:
439      wsString = L"can not found '%s' function";
440      return;
441    case XFA_IDS_NOT_ARRAY:
442      wsString = L"'%s' doesn't an array";
443      return;
444    case XFA_IDS_OUT_ARRAY:
445      wsString = L"out of range of '%s' array";
446      return;
447    case XFA_IDS_NOT_SUPPORT_CALC:
448      wsString = L"'%s' operator can not support array calculate";
449      return;
450    case XFA_IDS_ARGUMENT_NOT_ARRAY:
451      wsString = L"'%s' function's %d argument can not be array";
452      return;
453    case XFA_IDS_ARGUMENT_EXPECT_CONTAINER:
454      wsString = L"'%s' argument expected a container";
455      return;
456    case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT:
457      wsString =
458          L"an attempt was made to reference property '%s' of a non-object in "
459          L"SOM expression %s";
460      return;
461    case XFA_IDS_FUNCTION_IS_BUILDIN:
462      wsString = L"function '%s' is buildin";
463      return;
464    case XFA_IDS_ERROR_MSG:
465      wsString = L"%s : %s";
466      return;
467    case XFA_IDS_INDEX_OUT_OF_BOUNDS:
468      wsString = L"Index value is out of bounds";
469      return;
470    case XFA_IDS_INCORRECT_NUMBER_OF_METHOD:
471      wsString = L"Incorrect number of parameters calling method '%s'";
472      return;
473    case XFA_IDS_ARGUMENT_MISMATCH:
474      wsString = L"Argument mismatch in property or function argument";
475      return;
476    case XFA_IDS_INVALID_ENUMERATE:
477      wsString = L"Invalid enumerated value: %s";
478      return;
479    case XFA_IDS_INVALID_APPEND:
480      wsString =
481          L"Invalid append operation: %s cannot have a child element of %s";
482      return;
483    case XFA_IDS_SOM_EXPECTED_LIST:
484      wsString =
485          L"SOM expression returned list when single result was expected";
486      return;
487    case XFA_IDS_NOT_HAVE_PROPERTY:
488      wsString = L"'%s' doesn't have property '%s'";
489      return;
490    case XFA_IDS_INVALID_NODE_TYPE:
491      wsString = L"Invalid node type : '%s'";
492      return;
493    case XFA_IDS_VIOLATE_BOUNDARY:
494      wsString =
495          L"The element [%s] has violated its allowable number of occurrences";
496      return;
497    case XFA_IDS_SERVER_DENY:
498      wsString = L"Server does not permit";
499      return;
500    case XFA_IDS_ValidateLimit:
501      wsString = FX_WSTRC(
502          L"Message limit exceeded. Remaining %d validation errors not "
503          L"reported.");
504      return;
505    case XFA_IDS_ValidateNullWarning:
506      wsString = FX_WSTRC(
507          L"%s cannot be left blank. To ignore validations for %s, click "
508          L"Ignore.");
509      return;
510    case XFA_IDS_ValidateNullError:
511      wsString = FX_WSTRC(L"%s cannot be left blank.");
512      return;
513    case XFA_IDS_ValidateWarning:
514      wsString = FX_WSTRC(
515          L"The value you entered for %s is invalid. To ignore validations for "
516          L"%s, click Ignore.");
517      return;
518    case XFA_IDS_ValidateError:
519      wsString = FX_WSTRC(L"The value you entered for %s is invalid.");
520      return;
521  }
522}
523
524FX_BOOL CPDFXFA_App::ShowFileDialog(const CFX_WideStringC& wsTitle,
525                                    const CFX_WideStringC& wsFilter,
526                                    CFX_WideStringArray& wsPathArr,
527                                    FX_BOOL bOpen) {
528  return FALSE;
529}
530
531IFWL_AdapterTimerMgr* CPDFXFA_App::GetTimerMgr() {
532  CXFA_FWLAdapterTimerMgr* pAdapter = NULL;
533  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
534  if (pEnv)
535    pAdapter = new CXFA_FWLAdapterTimerMgr(pEnv);
536  return pAdapter;
537}
538