Index: fpdfsdk/cpdfsdk_interform.cpp |
diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..65e778d2c46dc298a9dd02d9908a9ea01f88a8e6 |
--- /dev/null |
+++ b/fpdfsdk/cpdfsdk_interform.cpp |
@@ -0,0 +1,726 @@ |
+// 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/include/cpdfsdk_interform.h" |
+ |
+#include <algorithm> |
+#include <memory> |
+ |
+#include "core/fpdfapi/fpdf_page/include/cpdf_page.h" |
+#include "core/fpdfapi/fpdf_parser/include/cfdf_document.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
+#include "core/fpdfdoc/include/cpdf_actionfields.h" |
+#include "core/fpdfdoc/include/cpdf_interform.h" |
+#include "core/fxge/include/cfx_graphstatedata.h" |
+#include "core/fxge/include/cfx_pathdata.h" |
+#include "core/fxge/include/cfx_renderdevice.h" |
+#include "fpdfsdk/formfiller/cffl_formfiller.h" |
+#include "fpdfsdk/fxedit/include/fxet_edit.h" |
+#include "fpdfsdk/include/cba_annotiterator.h" |
+#include "fpdfsdk/include/cpdfsdk_annot.h" |
+#include "fpdfsdk/include/cpdfsdk_widget.h" |
+#include "fpdfsdk/include/fsdk_actionhandler.h" |
+#include "fpdfsdk/include/fsdk_define.h" |
+#include "fpdfsdk/include/fsdk_mgr.h" |
+#include "fpdfsdk/include/ipdfsdk_annothandler.h" |
+#include "fpdfsdk/javascript/ijs_context.h" |
+#include "fpdfsdk/javascript/ijs_runtime.h" |
+#include "fpdfsdk/pdfwindow/PWL_Utils.h" |
+#include "third_party/base/stl_util.h" |
+ |
+#ifdef PDF_ENABLE_XFA |
+#include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h" |
+#include "fpdfsdk/fpdfxfa/include/fpdfxfa_util.h" |
+#include "fpdfsdk/include/cpdfsdk_xfawidget.h" |
+#include "xfa/fxfa/include/cxfa_eventparam.h" |
+#include "xfa/fxfa/include/xfa_ffdocview.h" |
+#include "xfa/fxfa/include/xfa_ffwidget.h" |
+#include "xfa/fxfa/include/xfa_ffwidgethandler.h" |
+#endif // PDF_ENABLE_XFA |
+ |
+CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument) |
+ : m_pDocument(pDocument), |
+ m_pInterForm(new CPDF_InterForm(m_pDocument->GetPDFDocument())), |
+#ifdef PDF_ENABLE_XFA |
+ m_bXfaCalculate(TRUE), |
+ m_bXfaValidationsEnabled(TRUE), |
+#endif // PDF_ENABLE_XFA |
+ m_bCalculate(TRUE), |
+ m_bBusy(FALSE), |
+ m_iHighlightAlpha(0) { |
+ m_pInterForm->SetFormNotify(this); |
+ for (int i = 0; i < kNumFieldTypes; ++i) |
+ m_bNeedHightlight[i] = FALSE; |
+} |
+ |
+CPDFSDK_InterForm::~CPDFSDK_InterForm() { |
+ m_Map.clear(); |
+#ifdef PDF_ENABLE_XFA |
+ m_XFAMap.clear(); |
+#endif // PDF_ENABLE_XFA |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::HighlightWidgets() { |
+ return FALSE; |
+} |
+ |
+CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget, |
+ FX_BOOL bNext) const { |
+ std::unique_ptr<CBA_AnnotIterator> pIterator( |
+ new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", "")); |
+ |
+ if (bNext) |
+ return static_cast<CPDFSDK_Widget*>(pIterator->GetNextAnnot(pWidget)); |
+ |
+ return static_cast<CPDFSDK_Widget*>(pIterator->GetPrevAnnot(pWidget)); |
+} |
+ |
+CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl, |
+ bool createIfNeeded) const { |
+ if (!pControl || !m_pInterForm) |
+ return nullptr; |
+ |
+ CPDFSDK_Widget* pWidget = nullptr; |
+ const auto it = m_Map.find(pControl); |
+ if (it != m_Map.end()) |
+ pWidget = it->second; |
+ if (pWidget) |
+ return pWidget; |
+ if (!createIfNeeded) |
+ return nullptr; |
+ |
+ CPDF_Dictionary* pControlDict = pControl->GetWidget(); |
+ CPDF_Document* pDocument = m_pDocument->GetPDFDocument(); |
+ CPDFSDK_PageView* pPage = nullptr; |
+ |
+ if (CPDF_Dictionary* pPageDict = pControlDict->GetDictBy("P")) { |
+ int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum()); |
+ if (nPageIndex >= 0) |
+ pPage = m_pDocument->GetPageView(nPageIndex); |
+ } |
+ |
+ if (!pPage) { |
+ int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict); |
+ if (nPageIndex >= 0) |
+ pPage = m_pDocument->GetPageView(nPageIndex); |
+ } |
+ |
+ if (!pPage) |
+ return nullptr; |
+ |
+ return static_cast<CPDFSDK_Widget*>(pPage->GetAnnotByDict(pControlDict)); |
+} |
+ |
+void CPDFSDK_InterForm::GetWidgets( |
+ const CFX_WideString& sFieldName, |
+ std::vector<CPDFSDK_Widget*>* widgets) const { |
+ for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) { |
+ CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName); |
+ ASSERT(pFormField); |
+ GetWidgets(pFormField, widgets); |
+ } |
+} |
+ |
+void CPDFSDK_InterForm::GetWidgets( |
+ CPDF_FormField* pField, |
+ std::vector<CPDFSDK_Widget*>* widgets) const { |
+ for (int i = 0, sz = pField->CountControls(); i < sz; ++i) { |
+ CPDF_FormControl* pFormCtrl = pField->GetControl(i); |
+ ASSERT(pFormCtrl); |
+ CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, true); |
+ if (pWidget) |
+ widgets->push_back(pWidget); |
+ } |
+} |
+ |
+int CPDFSDK_InterForm::GetPageIndexByAnnotDict( |
+ CPDF_Document* pDocument, |
+ CPDF_Dictionary* pAnnotDict) const { |
+ ASSERT(pAnnotDict); |
+ |
+ for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) { |
+ if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) { |
+ if (CPDF_Array* pAnnots = pPageDict->GetArrayBy("Annots")) { |
+ for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) { |
+ CPDF_Object* pDict = pAnnots->GetDirectObjectAt(j); |
+ if (pAnnotDict == pDict) |
+ return i; |
+ } |
+ } |
+ } |
+ } |
+ |
+ return -1; |
+} |
+ |
+void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl, |
+ CPDFSDK_Widget* pWidget) { |
+ m_Map[pControl] = pWidget; |
+} |
+ |
+void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) { |
+ m_Map.erase(pControl); |
+} |
+ |
+void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) { |
+ m_bCalculate = bEnabled; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const { |
+ return m_bCalculate; |
+} |
+ |
+#ifdef PDF_ENABLE_XFA |
+void CPDFSDK_InterForm::AddXFAMap(CXFA_FFWidget* hWidget, |
+ CPDFSDK_XFAWidget* pWidget) { |
+ ASSERT(hWidget); |
+ m_XFAMap[hWidget] = pWidget; |
+} |
+ |
+void CPDFSDK_InterForm::RemoveXFAMap(CXFA_FFWidget* hWidget) { |
+ ASSERT(hWidget); |
+ m_XFAMap.erase(hWidget); |
+} |
+ |
+CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(CXFA_FFWidget* hWidget) { |
+ ASSERT(hWidget); |
+ auto it = m_XFAMap.find(hWidget); |
+ return it != m_XFAMap.end() ? it->second : nullptr; |
+} |
+ |
+void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) { |
+ m_bXfaCalculate = bEnabled; |
+} |
+FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const { |
+ return m_bXfaCalculate; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() { |
+ return m_bXfaValidationsEnabled; |
+} |
+void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) { |
+ m_bXfaValidationsEnabled = bEnabled; |
+} |
+ |
+void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField, |
+ FX_BOOL bSynchronizeElse) { |
+ for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { |
+ CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); |
+ if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) |
+ pWidget->Synchronize(bSynchronizeElse); |
+ } |
+} |
+#endif // PDF_ENABLE_XFA |
+ |
+void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) { |
+ CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); |
+ ASSERT(pEnv); |
+ if (!pEnv->IsJSInitiated()) |
+ return; |
+ |
+ if (m_bBusy) |
+ return; |
+ |
+ m_bBusy = TRUE; |
+ |
+ if (!IsCalculateEnabled()) { |
+ m_bBusy = FALSE; |
+ return; |
+ } |
+ |
+ IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime(); |
+ pRuntime->SetReaderDocument(m_pDocument); |
+ |
+ int nSize = m_pInterForm->CountFieldsInCalculationOrder(); |
+ for (int i = 0; i < nSize; i++) { |
+ CPDF_FormField* pField = m_pInterForm->GetFieldInCalculationOrder(i); |
+ if (!pField) |
+ continue; |
+ |
+ int nType = pField->GetFieldType(); |
+ if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD) |
+ continue; |
+ |
+ CPDF_AAction aAction = pField->GetAdditionalAction(); |
+ if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Calculate)) |
+ continue; |
+ |
+ CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate); |
+ if (!action.GetDict()) |
+ continue; |
+ |
+ CFX_WideString csJS = action.GetJavaScript(); |
+ if (csJS.IsEmpty()) |
+ continue; |
+ |
+ IJS_Context* pContext = pRuntime->NewContext(); |
+ CFX_WideString sOldValue = pField->GetValue(); |
+ CFX_WideString sValue = sOldValue; |
+ FX_BOOL bRC = TRUE; |
+ pContext->OnField_Calculate(pFormField, pField, sValue, bRC); |
+ |
+ CFX_WideString sInfo; |
+ FX_BOOL bRet = pContext->RunScript(csJS, &sInfo); |
+ pRuntime->ReleaseContext(pContext); |
+ |
+ if (bRet && bRC && sValue.Compare(sOldValue) != 0) |
+ pField->SetValue(sValue, TRUE); |
+ } |
+ |
+ m_bBusy = FALSE; |
+} |
+ |
+CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField, |
+ FX_BOOL& bFormated) { |
+ CFX_WideString sValue = pFormField->GetValue(); |
+ CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); |
+ ASSERT(pEnv); |
+ if (!pEnv->IsJSInitiated()) { |
+ bFormated = FALSE; |
+ return sValue; |
+ } |
+ |
+ IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime(); |
+ pRuntime->SetReaderDocument(m_pDocument); |
+ |
+ if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX && |
+ pFormField->CountSelectedItems() > 0) { |
+ int index = pFormField->GetSelectedIndex(0); |
+ if (index >= 0) |
+ sValue = pFormField->GetOptionLabel(index); |
+ } |
+ |
+ bFormated = FALSE; |
+ |
+ CPDF_AAction aAction = pFormField->GetAdditionalAction(); |
+ if (aAction.GetDict() && aAction.ActionExist(CPDF_AAction::Format)) { |
+ CPDF_Action action = aAction.GetAction(CPDF_AAction::Format); |
+ if (action.GetDict()) { |
+ CFX_WideString script = action.GetJavaScript(); |
+ if (!script.IsEmpty()) { |
+ CFX_WideString Value = sValue; |
+ |
+ IJS_Context* pContext = pRuntime->NewContext(); |
+ pContext->OnField_Format(pFormField, Value, TRUE); |
+ CFX_WideString sInfo; |
+ FX_BOOL bRet = pContext->RunScript(script, &sInfo); |
+ pRuntime->ReleaseContext(pContext); |
+ |
+ if (bRet) { |
+ sValue = Value; |
+ bFormated = TRUE; |
+ } |
+ } |
+ } |
+ } |
+ |
+ return sValue; |
+} |
+ |
+void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField, |
+ const FX_WCHAR* sValue, |
+ FX_BOOL bValueChanged) { |
+ for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { |
+ CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); |
+ ASSERT(pFormCtrl); |
+ if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) |
+ pWidget->ResetAppearance(sValue, bValueChanged); |
+ } |
+} |
+ |
+void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) { |
+ for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { |
+ CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); |
+ ASSERT(pFormCtrl); |
+ |
+ if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) { |
+ CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); |
+ CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller(); |
+ UnderlyingPageType* pPage = pWidget->GetUnderlyingPage(); |
+ CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, false); |
+ FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget); |
+ |
+ pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right, |
+ rcBBox.bottom); |
+ } |
+ } |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField, |
+ const CFX_WideString& csValue) { |
+ CPDF_AAction aAction = pFormField->GetAdditionalAction(); |
+ if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::KeyStroke)) |
+ return TRUE; |
+ |
+ CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke); |
+ if (!action.GetDict()) |
+ return TRUE; |
+ |
+ CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); |
+ CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander(); |
+ PDFSDK_FieldAction fa; |
+ fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0); |
+ fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0); |
+ fa.sValue = csValue; |
+ pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke, |
+ m_pDocument, pFormField, fa); |
+ return fa.bRC; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField, |
+ const CFX_WideString& csValue) { |
+ CPDF_AAction aAction = pFormField->GetAdditionalAction(); |
+ if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Validate)) |
+ return TRUE; |
+ |
+ CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate); |
+ if (!action.GetDict()) |
+ return TRUE; |
+ |
+ CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); |
+ CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander(); |
+ PDFSDK_FieldAction fa; |
+ fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0); |
+ fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0); |
+ fa.sValue = csValue; |
+ pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate, |
+ m_pDocument, pFormField, fa); |
+ return fa.bRC; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) { |
+ ASSERT(action.GetDict()); |
+ |
+ CPDF_ActionFields af(&action); |
+ std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); |
+ std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); |
+ |
+ bool bHide = action.GetHideStatus(); |
+ FX_BOOL bChanged = FALSE; |
+ |
+ for (CPDF_FormField* pField : fields) { |
+ for (int i = 0, sz = pField->CountControls(); i < sz; ++i) { |
+ CPDF_FormControl* pControl = pField->GetControl(i); |
+ ASSERT(pControl); |
+ |
+ if (CPDFSDK_Widget* pWidget = GetWidget(pControl, false)) { |
+ uint32_t nFlags = pWidget->GetFlags(); |
+ nFlags &= ~ANNOTFLAG_INVISIBLE; |
+ nFlags &= ~ANNOTFLAG_NOVIEW; |
+ if (bHide) |
+ nFlags |= ANNOTFLAG_HIDDEN; |
+ else |
+ nFlags &= ~ANNOTFLAG_HIDDEN; |
+ pWidget->SetFlags(nFlags); |
+ pWidget->GetPageView()->UpdateView(pWidget); |
+ bChanged = TRUE; |
+ } |
+ } |
+ } |
+ |
+ return bChanged; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) { |
+ CFX_WideString sDestination = action.GetFilePath(); |
+ if (sDestination.IsEmpty()) |
+ return FALSE; |
+ |
+ CPDF_Dictionary* pActionDict = action.GetDict(); |
+ if (pActionDict->KeyExist("Fields")) { |
+ CPDF_ActionFields af(&action); |
+ uint32_t dwFlags = action.GetFlags(); |
+ std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); |
+ std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); |
+ if (!fields.empty()) { |
+ bool bIncludeOrExclude = !(dwFlags & 0x01); |
+ if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude)) |
+ return FALSE; |
+ |
+ return SubmitFields(sDestination, fields, bIncludeOrExclude, false); |
+ } |
+ } |
+ if (m_pInterForm->CheckRequiredFields(nullptr, true)) |
+ return FALSE; |
+ |
+ return SubmitForm(sDestination, FALSE); |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::SubmitFields( |
+ const CFX_WideString& csDestination, |
+ const std::vector<CPDF_FormField*>& fields, |
+ bool bIncludeOrExclude, |
+ bool bUrlEncoded) { |
+ CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); |
+ |
+ CFX_ByteTextBuf textBuf; |
+ ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf); |
+ |
+ uint8_t* pBuffer = textBuf.GetBuffer(); |
+ FX_STRSIZE nBufSize = textBuf.GetLength(); |
+ |
+ if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize)) |
+ return FALSE; |
+ |
+ pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str()); |
+ return TRUE; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile, |
+ CFX_WideString csTxtFile) { |
+ return TRUE; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf, |
+ FX_STRSIZE& nBufSize) { |
+ CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize); |
+ if (!pFDF) |
+ return TRUE; |
+ |
+ CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictBy("FDF"); |
+ if (!pMainDict) |
+ return FALSE; |
+ |
+ CPDF_Array* pFields = pMainDict->GetArrayBy("Fields"); |
+ if (!pFields) |
+ return FALSE; |
+ |
+ CFX_ByteTextBuf fdfEncodedData; |
+ for (uint32_t i = 0; i < pFields->GetCount(); i++) { |
+ CPDF_Dictionary* pField = pFields->GetDictAt(i); |
+ if (!pField) |
+ continue; |
+ CFX_WideString name; |
+ name = pField->GetUnicodeTextBy("T"); |
+ CFX_ByteString name_b = CFX_ByteString::FromUnicode(name); |
+ CFX_ByteString csBValue = pField->GetStringBy("V"); |
+ CFX_WideString csWValue = PDF_DecodeText(csBValue); |
+ CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue); |
+ |
+ fdfEncodedData << name_b.GetBuffer(name_b.GetLength()); |
+ name_b.ReleaseBuffer(); |
+ fdfEncodedData << "="; |
+ fdfEncodedData << csValue_b.GetBuffer(csValue_b.GetLength()); |
+ csValue_b.ReleaseBuffer(); |
+ if (i != pFields->GetCount() - 1) |
+ fdfEncodedData << "&"; |
+ } |
+ |
+ nBufSize = fdfEncodedData.GetLength(); |
+ pBuf = FX_Alloc(uint8_t, nBufSize); |
+ FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize); |
+ return TRUE; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf( |
+ const std::vector<CPDF_FormField*>& fields, |
+ bool bIncludeOrExclude, |
+ CFX_ByteTextBuf& textBuf) { |
+ std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF( |
+ m_pDocument->GetPath().AsStringC(), fields, bIncludeOrExclude)); |
+ return pFDF ? pFDF->WriteBuf(textBuf) : FALSE; |
+} |
+ |
+CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName( |
+ const CFX_WideString& sFileExt) { |
+ return L""; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination, |
+ FX_BOOL bUrlEncoded) { |
+ if (sDestination.IsEmpty()) |
+ return FALSE; |
+ |
+ if (!m_pDocument || !m_pInterForm) |
+ return FALSE; |
+ |
+ CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); |
+ CFX_WideString wsPDFFilePath = m_pDocument->GetPath(); |
+ CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath.AsStringC()); |
+ if (!pFDFDoc) |
+ return FALSE; |
+ |
+ CFX_ByteTextBuf FdfBuffer; |
+ FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer); |
+ delete pFDFDoc; |
+ if (!bRet) |
+ return FALSE; |
+ |
+ uint8_t* pBuffer = FdfBuffer.GetBuffer(); |
+ FX_STRSIZE nBufSize = FdfBuffer.GetLength(); |
+ |
+ if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize)) |
+ return FALSE; |
+ |
+ pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str()); |
+ |
+ if (bUrlEncoded) |
+ FX_Free(pBuffer); |
+ |
+ return TRUE; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) { |
+ CFDF_Document* pFDF = |
+ m_pInterForm->ExportToFDF(m_pDocument->GetPath().AsStringC()); |
+ if (!pFDF) |
+ return FALSE; |
+ |
+ FX_BOOL bRet = pFDF->WriteBuf(textBuf); |
+ delete pFDF; |
+ |
+ return bRet; |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) { |
+ ASSERT(action.GetDict()); |
+ |
+ CPDF_Dictionary* pActionDict = action.GetDict(); |
+ if (!pActionDict->KeyExist("Fields")) |
+ return m_pInterForm->ResetForm(true); |
+ |
+ CPDF_ActionFields af(&action); |
+ uint32_t dwFlags = action.GetFlags(); |
+ |
+ std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); |
+ std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); |
+ return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true); |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) { |
+ return FALSE; |
+} |
+ |
+std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects( |
+ const std::vector<CPDF_Object*>& objects) const { |
+ std::vector<CPDF_FormField*> fields; |
+ for (CPDF_Object* pObject : objects) { |
+ if (pObject && pObject->IsString()) { |
+ CFX_WideString csName = pObject->GetUnicodeText(); |
+ CPDF_FormField* pField = m_pInterForm->GetField(0, csName); |
+ if (pField) |
+ fields.push_back(pField); |
+ } |
+ } |
+ return fields; |
+} |
+ |
+int CPDFSDK_InterForm::BeforeValueChange(CPDF_FormField* pField, |
+ const CFX_WideString& csValue) { |
+ int nType = pField->GetFieldType(); |
+ if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD) |
+ return 0; |
+ |
+ if (!OnKeyStrokeCommit(pField, csValue)) |
+ return -1; |
+ |
+ if (!OnValidate(pField, csValue)) |
+ return -1; |
+ |
+ return 1; |
+} |
+ |
+void CPDFSDK_InterForm::AfterValueChange(CPDF_FormField* pField) { |
+#ifdef PDF_ENABLE_XFA |
+ SynchronizeField(pField, FALSE); |
+#endif // PDF_ENABLE_XFA |
+ int nType = pField->GetFieldType(); |
+ if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) { |
+ OnCalculate(pField); |
+ FX_BOOL bFormated = FALSE; |
+ CFX_WideString sValue = OnFormat(pField, bFormated); |
+ ResetFieldAppearance(pField, bFormated ? sValue.c_str() : nullptr, TRUE); |
+ UpdateField(pField); |
+ } |
+} |
+ |
+int CPDFSDK_InterForm::BeforeSelectionChange(CPDF_FormField* pField, |
+ const CFX_WideString& csValue) { |
+ if (pField->GetFieldType() != FIELDTYPE_LISTBOX) |
+ return 0; |
+ |
+ if (!OnKeyStrokeCommit(pField, csValue)) |
+ return -1; |
+ |
+ if (!OnValidate(pField, csValue)) |
+ return -1; |
+ |
+ return 1; |
+} |
+ |
+void CPDFSDK_InterForm::AfterSelectionChange(CPDF_FormField* pField) { |
+ if (pField->GetFieldType() != FIELDTYPE_LISTBOX) |
+ return; |
+ |
+ OnCalculate(pField); |
+ ResetFieldAppearance(pField, nullptr, TRUE); |
+ UpdateField(pField); |
+} |
+ |
+void CPDFSDK_InterForm::AfterCheckedStatusChange(CPDF_FormField* pField) { |
+ int nType = pField->GetFieldType(); |
+ if (nType != FIELDTYPE_CHECKBOX && nType != FIELDTYPE_RADIOBUTTON) |
+ return; |
+ |
+ OnCalculate(pField); |
+ UpdateField(pField); |
+} |
+ |
+int CPDFSDK_InterForm::BeforeFormReset(CPDF_InterForm* pForm) { |
+ return 0; |
+} |
+ |
+void CPDFSDK_InterForm::AfterFormReset(CPDF_InterForm* pForm) { |
+ OnCalculate(nullptr); |
+} |
+ |
+int CPDFSDK_InterForm::BeforeFormImportData(CPDF_InterForm* pForm) { |
+ return 0; |
+} |
+ |
+void CPDFSDK_InterForm::AfterFormImportData(CPDF_InterForm* pForm) { |
+ OnCalculate(nullptr); |
+} |
+ |
+FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) { |
+ if (nFieldType < 1 || nFieldType > kNumFieldTypes) |
+ return FALSE; |
+ return m_bNeedHightlight[nFieldType - 1]; |
+} |
+ |
+void CPDFSDK_InterForm::RemoveAllHighLight() { |
+ for (int i = 0; i < kNumFieldTypes; ++i) |
+ m_bNeedHightlight[i] = FALSE; |
+} |
+ |
+void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) { |
+ if (nFieldType < 0 || nFieldType > kNumFieldTypes) |
+ return; |
+ switch (nFieldType) { |
+ case 0: { |
+ for (int i = 0; i < kNumFieldTypes; ++i) { |
+ m_aHighlightColor[i] = clr; |
+ m_bNeedHightlight[i] = TRUE; |
+ } |
+ break; |
+ } |
+ default: { |
+ m_aHighlightColor[nFieldType - 1] = clr; |
+ m_bNeedHightlight[nFieldType - 1] = TRUE; |
+ break; |
+ } |
+ } |
+} |
+ |
+FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) { |
+ if (nFieldType < 0 || nFieldType > kNumFieldTypes) |
+ return FXSYS_RGB(255, 255, 255); |
+ if (nFieldType == 0) |
+ return m_aHighlightColor[0]; |
+ return m_aHighlightColor[nFieldType - 1]; |
+} |