summaryrefslogtreecommitdiff
path: root/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp')
-rw-r--r--fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp1023
1 files changed, 1023 insertions, 0 deletions
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
new file mode 100644
index 0000000000..56eb3fccc6
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -0,0 +1,1023 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/fpdfxfa/include/cpdfxfa_docenvironment.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
+#include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h"
+#include "fpdfsdk/fpdfxfa/include/fpdfxfa_page.h"
+#include "fpdfsdk/include/cpdfdoc_environment.h"
+#include "fpdfsdk/include/cpdfsdk_document.h"
+#include "fpdfsdk/include/cpdfsdk_interform.h"
+#include "fpdfsdk/include/cpdfsdk_pageview.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "xfa/fxfa/include/xfa_ffdocview.h"
+#include "xfa/fxfa/include/xfa_ffwidget.h"
+#include "xfa/fxfa/include/xfa_ffwidgethandler.h"
+
+#define IDS_XFA_Validate_Input \
+ "At least one required field was empty. Please fill in the required " \
+ "fields\r\n(highlighted) before continuing."
+
+// submit
+#define FXFA_CONFIG 0x00000001
+#define FXFA_TEMPLATE 0x00000010
+#define FXFA_LOCALESET 0x00000100
+#define FXFA_DATASETS 0x00001000
+#define FXFA_XMPMETA 0x00010000
+#define FXFA_XFDF 0x00100000
+#define FXFA_FORM 0x01000000
+#define FXFA_PDF 0x10000000
+#define FXFA_XFA_ALL 0x01111111
+
+CPDFXFA_DocEnvironment::CPDFXFA_DocEnvironment(CPDFXFA_Document* doc)
+ : m_pDocument(doc), m_pJSContext(nullptr) {
+ ASSERT(m_pDocument);
+}
+
+CPDFXFA_DocEnvironment::~CPDFXFA_DocEnvironment() {
+ if (m_pJSContext && m_pDocument->GetSDKDoc() &&
+ m_pDocument->GetSDKDoc()->GetEnv())
+ m_pDocument->GetSDKDoc()->GetEnv()->GetJSRuntime()->ReleaseContext(
+ m_pJSContext);
+}
+
+void CPDFXFA_DocEnvironment::SetChangeMark(CXFA_FFDoc* hDoc) {
+ if (hDoc == m_pDocument->GetXFADoc() && m_pDocument->GetSDKDoc())
+ m_pDocument->GetSDKDoc()->SetChangeMark();
+}
+
+void CPDFXFA_DocEnvironment::InvalidateRect(CXFA_FFPageView* pPageView,
+ const CFX_RectF& rt,
+ uint32_t dwFlags /* = 0 */) {
+ if (!m_pDocument->GetXFADoc() || !m_pDocument->GetSDKDoc())
+ return;
+
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA)
+ return;
+
+ CPDFXFA_Page* pPage = m_pDocument->GetPage(pPageView);
+ if (!pPage)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return;
+
+ CFX_FloatRect rcPage = CFX_FloatRect::FromCFXRectF(rt);
+ pEnv->FFI_Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom,
+ rcPage.right, rcPage.top);
+}
+
+void CPDFXFA_DocEnvironment::DisplayCaret(CXFA_FFWidget* hWidget,
+ FX_BOOL bVisible,
+ const CFX_RectF* pRtAnchor) {
+ if (!hWidget || !pRtAnchor || !m_pDocument->GetXFADoc() ||
+ !m_pDocument->GetSDKDoc() || !m_pDocument->GetXFADocView())
+ return;
+
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA)
+ return;
+
+ CXFA_FFWidgetHandler* pWidgetHandler =
+ m_pDocument->GetXFADocView()->GetWidgetHandler();
+ if (!pWidgetHandler)
+ return;
+
+ CXFA_FFPageView* pPageView = hWidget->GetPageView();
+ if (!pPageView)
+ return;
+
+ CPDFXFA_Page* pPage = m_pDocument->GetPage(pPageView);
+ if (!pPage)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return;
+
+ CFX_FloatRect rcCaret = CFX_FloatRect::FromCFXRectF(*pRtAnchor);
+ pEnv->FFI_DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, rcCaret.top,
+ rcCaret.right, rcCaret.bottom);
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::GetPopupPos(CXFA_FFWidget* hWidget,
+ FX_FLOAT fMinPopup,
+ FX_FLOAT fMaxPopup,
+ const CFX_RectF& rtAnchor,
+ CFX_RectF& rtPopup) {
+ if (!hWidget)
+ return FALSE;
+
+ CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
+ if (!pXFAPageView)
+ return FALSE;
+
+ CPDFXFA_Page* pPage = m_pDocument->GetPage(pXFAPageView);
+ if (!pPage)
+ return FALSE;
+
+ CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
+ int nRotate = pWidgetAcc->GetRotate();
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return FALSE;
+
+ FS_RECTF pageViewRect = {0.0f, 0.0f, 0.0f, 0.0f};
+ pEnv->FFI_GetPageViewRect(pPage, pageViewRect);
+
+ int t1;
+ int t2;
+ CFX_FloatRect rcAnchor = CFX_FloatRect::FromCFXRectF(rtAnchor);
+ switch (nRotate) {
+ case 90: {
+ t1 = (int)(pageViewRect.right - rcAnchor.right);
+ t2 = (int)(rcAnchor.left - pageViewRect.left);
+ if (rcAnchor.bottom < pageViewRect.bottom)
+ rtPopup.left += rcAnchor.bottom - pageViewRect.bottom;
+ break;
+ }
+ case 180: {
+ t2 = (int)(pageViewRect.top - rcAnchor.top);
+ t1 = (int)(rcAnchor.bottom - pageViewRect.bottom);
+ if (rcAnchor.left < pageViewRect.left)
+ rtPopup.left += rcAnchor.left - pageViewRect.left;
+ break;
+ }
+ case 270: {
+ t1 = (int)(rcAnchor.left - pageViewRect.left);
+ t2 = (int)(pageViewRect.right - rcAnchor.right);
+ if (rcAnchor.top > pageViewRect.top)
+ rtPopup.left -= rcAnchor.top - pageViewRect.top;
+ break;
+ }
+ case 0:
+ default: {
+ t1 = (int)(pageViewRect.top - rcAnchor.top);
+ t2 = (int)(rcAnchor.bottom - pageViewRect.bottom);
+ if (rcAnchor.right > pageViewRect.right)
+ rtPopup.left -= rcAnchor.right - pageViewRect.right;
+ break;
+ }
+ }
+
+ int t;
+ uint32_t dwPos;
+ if (t1 <= 0 && t2 <= 0)
+ return FALSE;
+ if (t1 <= 0) {
+ t = t2;
+ dwPos = 1;
+ } else if (t2 <= 0) {
+ t = t1;
+ dwPos = 0;
+ } else if (t1 > t2) {
+ t = t1;
+ dwPos = 0;
+ } else {
+ t = t2;
+ dwPos = 1;
+ }
+
+ FX_FLOAT fPopupHeight;
+ if (t < fMinPopup)
+ fPopupHeight = fMinPopup;
+ else if (t > fMaxPopup)
+ fPopupHeight = fMaxPopup;
+ else
+ fPopupHeight = static_cast<FX_FLOAT>(t);
+
+ switch (nRotate) {
+ case 0:
+ case 180: {
+ if (dwPos == 0) {
+ rtPopup.top = rtAnchor.height;
+ rtPopup.height = fPopupHeight;
+ } else {
+ rtPopup.top = -fPopupHeight;
+ rtPopup.height = fPopupHeight;
+ }
+ break;
+ }
+ case 90:
+ case 270: {
+ if (dwPos == 0) {
+ rtPopup.top = rtAnchor.width;
+ rtPopup.height = fPopupHeight;
+ } else {
+ rtPopup.top = -fPopupHeight;
+ rtPopup.height = fPopupHeight;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::PopupMenu(CXFA_FFWidget* hWidget,
+ CFX_PointF ptPopup) {
+ if (!hWidget)
+ return FALSE;
+
+ CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
+ if (!pXFAPageView)
+ return FALSE;
+
+ CPDFXFA_Page* pPage = m_pDocument->GetPage(pXFAPageView);
+ if (!pPage)
+ return FALSE;
+
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return FALSE;
+
+ int menuFlag = 0;
+ if (hWidget->CanUndo())
+ menuFlag |= FXFA_MENU_UNDO;
+ if (hWidget->CanRedo())
+ menuFlag |= FXFA_MENU_REDO;
+ if (hWidget->CanPaste())
+ menuFlag |= FXFA_MENU_PASTE;
+ if (hWidget->CanCopy())
+ menuFlag |= FXFA_MENU_COPY;
+ if (hWidget->CanCut())
+ menuFlag |= FXFA_MENU_CUT;
+ if (hWidget->CanSelectAll())
+ menuFlag |= FXFA_MENU_SELECTALL;
+
+ return pEnv->FFI_PopupMenu(pPage, hWidget, menuFlag, ptPopup, nullptr);
+}
+
+void CPDFXFA_DocEnvironment::PageViewEvent(CXFA_FFPageView* pPageView,
+ uint32_t dwFlags) {
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return;
+
+ if (m_pDocument->GetLoadStatus() == FXFA_LOADSTATUS_LOADING ||
+ m_pDocument->GetLoadStatus() == FXFA_LOADSTATUS_CLOSING ||
+ XFA_PAGEVIEWEVENT_StopLayout != dwFlags)
+ return;
+
+ int nNewCount = m_pDocument->GetPageCount();
+ if (nNewCount == m_pDocument->GetOriginalPageCount())
+ return;
+
+ CXFA_FFDocView* pXFADocView = m_pDocument->GetXFADocView();
+ if (!pXFADocView)
+ return;
+
+ for (int iPageIter = 0; iPageIter < m_pDocument->GetOriginalPageCount();
+ iPageIter++) {
+ CPDFXFA_Page* pPage = m_pDocument->GetXFAPageList()->GetAt(iPageIter);
+ if (!pPage)
+ continue;
+
+ m_pDocument->GetSDKDoc()->RemovePageView(pPage);
+ pPage->SetXFAPageView(pXFADocView->GetPageView(iPageIter));
+ }
+
+ int flag = (nNewCount < m_pDocument->GetOriginalPageCount())
+ ? FXFA_PAGEVIEWEVENT_POSTREMOVED
+ : FXFA_PAGEVIEWEVENT_POSTADDED;
+ int count = FXSYS_abs(nNewCount - m_pDocument->GetOriginalPageCount());
+ m_pDocument->SetOriginalPageCount(nNewCount);
+ pEnv->FFI_PageEvent(count, flag);
+}
+
+void CPDFXFA_DocEnvironment::WidgetPostAdd(CXFA_FFWidget* hWidget,
+ CXFA_WidgetAcc* pWidgetData) {
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA || !hWidget)
+ return;
+
+ CXFA_FFPageView* pPageView = hWidget->GetPageView();
+ if (!pPageView)
+ return;
+
+ CPDFXFA_Page* pXFAPage = m_pDocument->GetPage(pPageView);
+ if (!pXFAPage)
+ return;
+
+ m_pDocument->GetSDKDoc()->GetPageView(pXFAPage, true)->AddAnnot(hWidget);
+}
+
+void CPDFXFA_DocEnvironment::WidgetPreRemove(CXFA_FFWidget* hWidget,
+ CXFA_WidgetAcc* pWidgetData) {
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA || !hWidget)
+ return;
+
+ CXFA_FFPageView* pPageView = hWidget->GetPageView();
+ if (!pPageView)
+ return;
+
+ CPDFXFA_Page* pXFAPage = m_pDocument->GetPage(pPageView);
+ if (!pXFAPage)
+ return;
+
+ CPDFSDK_PageView* pSdkPageView =
+ m_pDocument->GetSDKDoc()->GetPageView(pXFAPage, true);
+ if (CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget))
+ pSdkPageView->DeleteAnnot(pAnnot);
+}
+
+int32_t CPDFXFA_DocEnvironment::CountPages(CXFA_FFDoc* hDoc) {
+ if (hDoc == m_pDocument->GetXFADoc() && m_pDocument->GetSDKDoc())
+ return m_pDocument->GetPageCount();
+ return 0;
+}
+
+int32_t CPDFXFA_DocEnvironment::GetCurrentPage(CXFA_FFDoc* hDoc) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetSDKDoc())
+ return -1;
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA)
+ return -1;
+
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return -1;
+
+ return pEnv->FFI_GetCurrentPageIndex(this);
+}
+
+void CPDFXFA_DocEnvironment::SetCurrentPage(CXFA_FFDoc* hDoc,
+ int32_t iCurPage) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetSDKDoc() ||
+ m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA || iCurPage < 0 ||
+ iCurPage >= m_pDocument->GetSDKDoc()->GetPageCount()) {
+ return;
+ }
+
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return;
+ pEnv->FFI_SetCurrentPage(this, iCurPage);
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::IsCalculationsEnabled(CXFA_FFDoc* hDoc) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetSDKDoc())
+ return FALSE;
+ if (m_pDocument->GetSDKDoc()->GetInterForm())
+ return m_pDocument->GetSDKDoc()->GetInterForm()->IsXfaCalculateEnabled();
+ return FALSE;
+}
+
+void CPDFXFA_DocEnvironment::SetCalculationsEnabled(CXFA_FFDoc* hDoc,
+ FX_BOOL bEnabled) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetSDKDoc())
+ return;
+ if (m_pDocument->GetSDKDoc()->GetInterForm())
+ m_pDocument->GetSDKDoc()->GetInterForm()->XfaEnableCalculate(bEnabled);
+}
+
+void CPDFXFA_DocEnvironment::GetTitle(CXFA_FFDoc* hDoc,
+ CFX_WideString& wsTitle) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetPDFDoc())
+ return;
+
+ CPDF_Dictionary* pInfoDict = m_pDocument->GetPDFDoc()->GetInfo();
+ if (!pInfoDict)
+ return;
+
+ CFX_ByteString csTitle = pInfoDict->GetStringBy("Title");
+ wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength()));
+ csTitle.ReleaseBuffer(csTitle.GetLength());
+}
+
+void CPDFXFA_DocEnvironment::SetTitle(CXFA_FFDoc* hDoc,
+ const CFX_WideString& wsTitle) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetPDFDoc())
+ return;
+
+ if (CPDF_Dictionary* pInfoDict = m_pDocument->GetPDFDoc()->GetInfo())
+ pInfoDict->SetAt("Title", new CPDF_String(wsTitle));
+}
+
+void CPDFXFA_DocEnvironment::ExportData(CXFA_FFDoc* hDoc,
+ const CFX_WideString& wsFilePath,
+ FX_BOOL bXDP) {
+ if (hDoc != m_pDocument->GetXFADoc())
+ return;
+
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+ m_pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return;
+
+ int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML;
+ CFX_ByteString bs = wsFilePath.UTF16LE_Encode();
+ if (wsFilePath.IsEmpty()) {
+ if (!pEnv->GetFormFillInfo() || !pEnv->GetFormFillInfo()->m_pJsPlatform)
+ return;
+
+ CFX_WideString filepath = pEnv->JS_fieldBrowse();
+ bs = filepath.UTF16LE_Encode();
+ }
+ int len = bs.GetLength();
+ FPDF_FILEHANDLER* pFileHandler =
+ pEnv->FFI_OpenFile(bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML,
+ (FPDF_WIDESTRING)bs.GetBuffer(len), "wb");
+ bs.ReleaseBuffer(len);
+ if (!pFileHandler)
+ return;
+
+ CFPDF_FileStream fileWrite(pFileHandler);
+ CFX_ByteString content;
+ if (fileType == FXFA_SAVEAS_XML) {
+ content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+ fileWrite.WriteBlock(content.c_str(), fileWrite.GetSize(),
+ content.GetLength());
+ m_pDocument->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Data,
+ &fileWrite, nullptr);
+ } else if (fileType == FXFA_SAVEAS_XDP) {
+ if (!m_pDocument->GetPDFDoc())
+ return;
+
+ CPDF_Dictionary* pRoot = m_pDocument->GetPDFDoc()->GetRoot();
+ if (!pRoot)
+ return;
+
+ CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm");
+ if (!pAcroForm)
+ return;
+
+ CPDF_Array* pArray = ToArray(pAcroForm->GetObjectBy("XFA"));
+ if (!pArray)
+ return;
+
+ int size = pArray->GetCount();
+ for (int i = 1; i < size; i += 2) {
+ CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
+ CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1);
+ if (!pPrePDFObj->IsString())
+ continue;
+ if (!pPDFObj->IsReference())
+ continue;
+
+ CPDF_Stream* pStream = ToStream(pPDFObj->GetDirect());
+ if (!pStream)
+ continue;
+ if (pPrePDFObj->GetString() == "form") {
+ m_pDocument->GetXFADocView()->GetDoc()->SavePackage(
+ XFA_HASHCODE_Form, &fileWrite, nullptr);
+ continue;
+ }
+ if (pPrePDFObj->GetString() == "datasets") {
+ m_pDocument->GetXFADocView()->GetDoc()->SavePackage(
+ XFA_HASHCODE_Datasets, &fileWrite, nullptr);
+ continue;
+ }
+ if (i == size - 1) {
+ CFX_WideString wPath = CFX_WideString::FromUTF16LE(
+ reinterpret_cast<const unsigned short*>(bs.c_str()),
+ bs.GetLength() / sizeof(unsigned short));
+ CFX_ByteString bPath = wPath.UTF8Encode();
+ const char* szFormat =
+ "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";
+ content.Format(szFormat, bPath.c_str());
+ fileWrite.WriteBlock(content.c_str(), fileWrite.GetSize(),
+ content.GetLength());
+ }
+ std::unique_ptr<CPDF_StreamAcc> pAcc(new CPDF_StreamAcc);
+ pAcc->LoadAllData(pStream);
+ fileWrite.WriteBlock(pAcc->GetData(), fileWrite.GetSize(),
+ pAcc->GetSize());
+ }
+ }
+ if (!fileWrite.Flush()) {
+ // Ignoring flush error.
+ }
+}
+
+void CPDFXFA_DocEnvironment::GotoURL(CXFA_FFDoc* hDoc,
+ const CFX_WideString& bsURL,
+ FX_BOOL bAppend) {
+ if (hDoc != m_pDocument->GetXFADoc())
+ return;
+
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return;
+
+ CFX_WideStringC str(bsURL.c_str());
+
+ pEnv->FFI_GotoURL(this, str, bAppend);
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::IsValidationsEnabled(CXFA_FFDoc* hDoc) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetSDKDoc())
+ return FALSE;
+ if (m_pDocument->GetSDKDoc()->GetInterForm())
+ return m_pDocument->GetSDKDoc()->GetInterForm()->IsXfaValidationsEnabled();
+ return TRUE;
+}
+
+void CPDFXFA_DocEnvironment::SetValidationsEnabled(CXFA_FFDoc* hDoc,
+ FX_BOOL bEnabled) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetSDKDoc())
+ return;
+ if (m_pDocument->GetSDKDoc()->GetInterForm())
+ m_pDocument->GetSDKDoc()->GetInterForm()->XfaSetValidationsEnabled(
+ bEnabled);
+}
+
+void CPDFXFA_DocEnvironment::SetFocusWidget(CXFA_FFDoc* hDoc,
+ CXFA_FFWidget* hWidget) {
+ if (hDoc != m_pDocument->GetXFADoc())
+ return;
+
+ if (!hWidget) {
+ m_pDocument->GetSDKDoc()->SetFocusAnnot(nullptr);
+ return;
+ }
+
+ int pageViewCount = m_pDocument->GetSDKDoc()->GetPageViewCount();
+ for (int i = 0; i < pageViewCount; i++) {
+ CPDFSDK_PageView* pPageView = m_pDocument->GetSDKDoc()->GetPageView(i);
+ if (!pPageView)
+ continue;
+
+ CPDFSDK_Annot* pAnnot = pPageView->GetAnnotByXFAWidget(hWidget);
+ if (pAnnot) {
+ m_pDocument->GetSDKDoc()->SetFocusAnnot(pAnnot);
+ break;
+ }
+ }
+}
+
+void CPDFXFA_DocEnvironment::Print(CXFA_FFDoc* hDoc,
+ int32_t nStartPage,
+ int32_t nEndPage,
+ uint32_t dwOptions) {
+ if (hDoc != m_pDocument->GetXFADoc())
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv || !pEnv->GetFormFillInfo() ||
+ !pEnv->GetFormFillInfo()->m_pJsPlatform ||
+ !pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print) {
+ return;
+ }
+
+ pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(
+ pEnv->GetFormFillInfo()->m_pJsPlatform,
+ dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage,
+ dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage,
+ dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder,
+ dwOptions & XFA_PRINTOPT_PrintAnnot);
+}
+
+FX_ARGB CPDFXFA_DocEnvironment::GetHighlightColor(CXFA_FFDoc* hDoc) {
+ if (hDoc != m_pDocument->GetXFADoc() || !m_pDocument->GetSDKDoc())
+ return 0;
+
+ CPDFSDK_InterForm* pInterForm = m_pDocument->GetSDKDoc()->GetInterForm();
+ if (!pInterForm)
+ return 0;
+
+ return ArgbEncode(pInterForm->GetHighlightAlpha(),
+ pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA));
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::NotifySubmit(FX_BOOL bPrevOrPost) {
+ if (bPrevOrPost)
+ return OnBeforeNotifySubmit();
+
+ OnAfterNotifySubmit();
+ return TRUE;
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::OnBeforeNotifySubmit() {
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+ m_pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
+ return TRUE;
+
+ if (!m_pDocument->GetXFADocView())
+ return TRUE;
+
+ CXFA_FFWidgetHandler* pWidgetHandler =
+ m_pDocument->GetXFADocView()->GetWidgetHandler();
+ if (!pWidgetHandler)
+ return TRUE;
+
+ std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
+ m_pDocument->GetXFADocView()->CreateWidgetAccIterator());
+ if (pWidgetAccIterator) {
+ CXFA_EventParam Param;
+ Param.m_eType = XFA_EVENT_PreSubmit;
+ while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext())
+ pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);
+ }
+
+ pWidgetAccIterator.reset(
+ m_pDocument->GetXFADocView()->CreateWidgetAccIterator());
+ if (!pWidgetAccIterator)
+ return TRUE;
+
+ CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ while (pWidgetAcc) {
+ int fRet = pWidgetAcc->ProcessValidate(-1);
+ if (fRet == XFA_EVENTERROR_Error) {
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return FALSE;
+
+ CFX_WideString ws;
+ ws.FromLocal(IDS_XFA_Validate_Input);
+ CFX_ByteString bs = ws.UTF16LE_Encode();
+ int len = bs.GetLength();
+ pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len), (FPDF_WIDESTRING)L"",
+ 0, 1);
+ bs.ReleaseBuffer(len);
+ return FALSE;
+ }
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ }
+ m_pDocument->GetXFADocView()->UpdateDocView();
+
+ return TRUE;
+}
+
+void CPDFXFA_DocEnvironment::OnAfterNotifySubmit() {
+ if (m_pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+ m_pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
+ return;
+
+ if (!m_pDocument->GetXFADocView())
+ return;
+
+ CXFA_FFWidgetHandler* pWidgetHandler =
+ m_pDocument->GetXFADocView()->GetWidgetHandler();
+ if (!pWidgetHandler)
+ return;
+
+ std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
+ m_pDocument->GetXFADocView()->CreateWidgetAccIterator());
+ if (!pWidgetAccIterator)
+ return;
+
+ CXFA_EventParam Param;
+ Param.m_eType = XFA_EVENT_PostSubmit;
+ CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ while (pWidgetAcc) {
+ pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ }
+ m_pDocument->GetXFADocView()->UpdateDocView();
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::SubmitData(CXFA_FFDoc* hDoc,
+ CXFA_Submit submit) {
+ if (!NotifySubmit(TRUE) || !m_pDocument->GetXFADocView())
+ return FALSE;
+
+ m_pDocument->GetXFADocView()->UpdateDocView();
+ FX_BOOL ret = SubmitDataInternal(hDoc, submit);
+ NotifySubmit(FALSE);
+ return ret;
+}
+
+IFX_FileRead* CPDFXFA_DocEnvironment::OpenLinkedFile(
+ CXFA_FFDoc* hDoc,
+ const CFX_WideString& wsLink) {
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return FALSE;
+
+ CFX_ByteString bs = wsLink.UTF16LE_Encode();
+ int len = bs.GetLength();
+ FPDF_FILEHANDLER* pFileHandler =
+ pEnv->FFI_OpenFile(0, (FPDF_WIDESTRING)bs.GetBuffer(len), "rb");
+ bs.ReleaseBuffer(len);
+
+ if (!pFileHandler)
+ return nullptr;
+ return new CFPDF_FileStream(pFileHandler);
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler,
+ int fileType,
+ FPDF_DWORD encodeType,
+ FPDF_DWORD flag) {
+ if (!m_pDocument->GetXFADocView())
+ return FALSE;
+
+ CFX_ByteString content;
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return FALSE;
+
+ CFPDF_FileStream fileStream(pFileHandler);
+ if (fileType == FXFA_SAVEAS_XML) {
+ const char kContent[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+ fileStream.WriteBlock(kContent, 0, strlen(kContent));
+ m_pDocument->GetXFADoc()->SavePackage(XFA_HASHCODE_Data, &fileStream,
+ nullptr);
+ return TRUE;
+ }
+
+ if (fileType != FXFA_SAVEAS_XDP)
+ return TRUE;
+
+ if (!flag) {
+ flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
+ FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
+ }
+ if (!m_pDocument->GetPDFDoc()) {
+ fileStream.Flush();
+ return FALSE;
+ }
+
+ CPDF_Dictionary* pRoot = m_pDocument->GetPDFDoc()->GetRoot();
+ if (!pRoot) {
+ fileStream.Flush();
+ return FALSE;
+ }
+
+ CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm");
+ if (!pAcroForm) {
+ fileStream.Flush();
+ return FALSE;
+ }
+
+ CPDF_Array* pArray = ToArray(pAcroForm->GetObjectBy("XFA"));
+ if (!pArray) {
+ fileStream.Flush();
+ return FALSE;
+ }
+
+ int size = pArray->GetCount();
+ for (int i = 1; i < size; i += 2) {
+ CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
+ CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1);
+ if (!pPrePDFObj->IsString())
+ continue;
+ if (!pPDFObj->IsReference())
+ continue;
+
+ CPDF_Object* pDirectObj = pPDFObj->GetDirect();
+ if (!pDirectObj->IsStream())
+ continue;
+ if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG))
+ continue;
+ if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE))
+ continue;
+ if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET))
+ continue;
+ if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS))
+ continue;
+ if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA))
+ continue;
+ if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF))
+ continue;
+ if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM))
+ continue;
+ if (pPrePDFObj->GetString() == "form") {
+ m_pDocument->GetXFADoc()->SavePackage(XFA_HASHCODE_Form, &fileStream,
+ nullptr);
+ } else if (pPrePDFObj->GetString() == "datasets") {
+ m_pDocument->GetXFADoc()->SavePackage(XFA_HASHCODE_Datasets, &fileStream,
+ nullptr);
+ } else {
+ // PDF,creator.
+ }
+ }
+ return TRUE;
+}
+
+void CPDFXFA_DocEnvironment::ToXFAContentFlags(CFX_WideString csSrcContent,
+ FPDF_DWORD& flag) {
+ if (csSrcContent.Find(L" config ", 0) != -1)
+ flag |= FXFA_CONFIG;
+ if (csSrcContent.Find(L" template ", 0) != -1)
+ flag |= FXFA_TEMPLATE;
+ if (csSrcContent.Find(L" localeSet ", 0) != -1)
+ flag |= FXFA_LOCALESET;
+ if (csSrcContent.Find(L" datasets ", 0) != -1)
+ flag |= FXFA_DATASETS;
+ if (csSrcContent.Find(L" xmpmeta ", 0) != -1)
+ flag |= FXFA_XMPMETA;
+ if (csSrcContent.Find(L" xfdf ", 0) != -1)
+ flag |= FXFA_XFDF;
+ if (csSrcContent.Find(L" form ", 0) != -1)
+ flag |= FXFA_FORM;
+ if (flag == 0) {
+ flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
+ FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
+ }
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::MailToInfo(CFX_WideString& csURL,
+ CFX_WideString& csToAddress,
+ CFX_WideString& csCCAddress,
+ CFX_WideString& csBCCAddress,
+ CFX_WideString& csSubject,
+ CFX_WideString& csMsg) {
+ CFX_WideString srcURL = csURL;
+ srcURL.TrimLeft();
+ if (srcURL.Left(7).CompareNoCase(L"mailto:") != 0)
+ return FALSE;
+
+ int pos = srcURL.Find(L'?', 0);
+ CFX_WideString tmp;
+ if (pos == -1) {
+ pos = srcURL.Find(L'@', 0);
+ if (pos == -1)
+ return FALSE;
+
+ tmp = srcURL.Right(csURL.GetLength() - 7);
+ } else {
+ tmp = srcURL.Left(pos);
+ tmp = tmp.Right(tmp.GetLength() - 7);
+ }
+ tmp.TrimLeft();
+ tmp.TrimRight();
+
+ csToAddress = tmp;
+
+ srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1));
+ while (!srcURL.IsEmpty()) {
+ srcURL.TrimLeft();
+ srcURL.TrimRight();
+ pos = srcURL.Find(L'&', 0);
+
+ tmp = (pos == -1) ? srcURL : srcURL.Left(pos);
+ tmp.TrimLeft();
+ tmp.TrimRight();
+ if (tmp.GetLength() >= 3 && tmp.Left(3).CompareNoCase(L"cc=") == 0) {
+ tmp = tmp.Right(tmp.GetLength() - 3);
+ if (!csCCAddress.IsEmpty())
+ csCCAddress += L';';
+ csCCAddress += tmp;
+ } else if (tmp.GetLength() >= 4 &&
+ tmp.Left(4).CompareNoCase(L"bcc=") == 0) {
+ tmp = tmp.Right(tmp.GetLength() - 4);
+ if (!csBCCAddress.IsEmpty())
+ csBCCAddress += L';';
+ csBCCAddress += tmp;
+ } else if (tmp.GetLength() >= 8 &&
+ tmp.Left(8).CompareNoCase(L"subject=") == 0) {
+ tmp = tmp.Right(tmp.GetLength() - 8);
+ csSubject += tmp;
+ } else if (tmp.GetLength() >= 5 &&
+ tmp.Left(5).CompareNoCase(L"body=") == 0) {
+ tmp = tmp.Right(tmp.GetLength() - 5);
+ csMsg += tmp;
+ }
+ srcURL = (pos == -1) ? L"" : srcURL.Right(csURL.GetLength() - (pos + 1));
+ }
+ csToAddress.Replace(L",", L";");
+ csCCAddress.Replace(L",", L";");
+ csBCCAddress.Replace(L",", L";");
+ return TRUE;
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::SubmitDataInternal(CXFA_FFDoc* hDoc,
+ CXFA_Submit submit) {
+ CPDFDoc_Environment* pEnv = m_pDocument->GetSDKDoc()->GetEnv();
+ if (!pEnv)
+ return FALSE;
+
+ CFX_WideStringC csURLC;
+ submit.GetSubmitTarget(csURLC);
+ CFX_WideString csURL(csURLC);
+ if (csURL.IsEmpty()) {
+ CFX_WideString ws;
+ ws.FromLocal("Submit cancelled.");
+ CFX_ByteString bs = ws.UTF16LE_Encode();
+ int len = bs.GetLength();
+ pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len), (FPDF_WIDESTRING)L"", 0,
+ 4);
+ bs.ReleaseBuffer(len);
+ return FALSE;
+ }
+
+ FPDF_BOOL bRet = TRUE;
+ FPDF_FILEHANDLER* pFileHandler = nullptr;
+ int fileFlag = -1;
+ switch (submit.GetSubmitFormat()) {
+ case XFA_ATTRIBUTEENUM_Xdp: {
+ CFX_WideStringC csContentC;
+ submit.GetSubmitXDPContent(csContentC);
+ CFX_WideString csContent;
+ csContent = csContentC;
+ csContent.TrimLeft();
+ csContent.TrimRight();
+ CFX_WideString space;
+ space.FromLocal(" ");
+ csContent = space + csContent + space;
+ FPDF_DWORD flag = 0;
+ if (submit.IsSubmitEmbedPDF())
+ flag |= FXFA_PDF;
+
+ ToXFAContentFlags(csContent, flag);
+ pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XDP, nullptr, "wb");
+ fileFlag = FXFA_SAVEAS_XDP;
+ ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag);
+ break;
+ }
+ case XFA_ATTRIBUTEENUM_Xml:
+ pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, nullptr, "wb");
+ fileFlag = FXFA_SAVEAS_XML;
+ ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL);
+ break;
+ case XFA_ATTRIBUTEENUM_Pdf:
+ break;
+ case XFA_ATTRIBUTEENUM_Urlencoded:
+ pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, nullptr, "wb");
+ fileFlag = FXFA_SAVEAS_XML;
+ ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL);
+ break;
+ default:
+ return false;
+ }
+ if (!pFileHandler)
+ return FALSE;
+ if (csURL.Left(7).CompareNoCase(L"mailto:") == 0) {
+ CFX_WideString csToAddress;
+ CFX_WideString csCCAddress;
+ CFX_WideString csBCCAddress;
+ CFX_WideString csSubject;
+ CFX_WideString csMsg;
+ bRet = MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject,
+ csMsg);
+ if (!bRet)
+ return FALSE;
+
+ CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode();
+ CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode();
+ CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode();
+ CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode();
+ CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode();
+ FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());
+ FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());
+ FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());
+ FPDF_WIDESTRING pSubject =
+ (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());
+ FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
+ pEnv->FFI_EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg);
+ bsTo.ReleaseBuffer();
+ bsCC.ReleaseBuffer();
+ bsBcc.ReleaseBuffer();
+ bsSubject.ReleaseBuffer();
+ bsMsg.ReleaseBuffer();
+ } else {
+ // HTTP or FTP
+ CFX_WideString ws;
+ CFX_ByteString bs = csURL.UTF16LE_Encode();
+ int len = bs.GetLength();
+ pEnv->FFI_UploadTo(pFileHandler, fileFlag,
+ (FPDF_WIDESTRING)bs.GetBuffer(len));
+ bs.ReleaseBuffer(len);
+ }
+ return bRet;
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::SetGlobalProperty(
+ CXFA_FFDoc* hDoc,
+ const CFX_ByteStringC& szPropName,
+ CFXJSE_Value* pValue) {
+ if (hDoc != m_pDocument->GetXFADoc())
+ return FALSE;
+
+ if (m_pDocument->GetSDKDoc() &&
+ m_pDocument->GetSDKDoc()->GetEnv()->GetJSRuntime())
+ return m_pDocument->GetSDKDoc()->GetEnv()->GetJSRuntime()->SetValueByName(
+ szPropName, pValue);
+ return FALSE;
+}
+
+FX_BOOL CPDFXFA_DocEnvironment::GetGlobalProperty(
+ CXFA_FFDoc* hDoc,
+ const CFX_ByteStringC& szPropName,
+ CFXJSE_Value* pValue) {
+ if (hDoc != m_pDocument->GetXFADoc())
+ return FALSE;
+ if (!m_pDocument->GetSDKDoc() ||
+ !m_pDocument->GetSDKDoc()->GetEnv()->GetJSRuntime())
+ return FALSE;
+
+ if (!m_pJSContext) {
+ m_pDocument->GetSDKDoc()->GetEnv()->GetJSRuntime()->SetReaderDocument(
+ m_pDocument->GetSDKDoc());
+ m_pJSContext =
+ m_pDocument->GetSDKDoc()->GetEnv()->GetJSRuntime()->NewContext();
+ }
+
+ return m_pDocument->GetSDKDoc()->GetEnv()->GetJSRuntime()->GetValueByName(
+ szPropName, pValue);
+}