summaryrefslogtreecommitdiff
path: root/fpdfsdk/cpdfsdk_formfillenvironment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fpdfsdk/cpdfsdk_formfillenvironment.cpp')
-rw-r--r--fpdfsdk/cpdfsdk_formfillenvironment.cpp217
1 files changed, 214 insertions, 3 deletions
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
index 7b41ea148c..2beaadeb1a 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.cpp
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
@@ -8,8 +8,12 @@
#include <memory>
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfdoc/cpdf_docjsactions.h"
#include "fpdfsdk/cpdfsdk_annothandlermgr.h"
-#include "fpdfsdk/cpdfsdk_document.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
#include "fpdfsdk/fsdk_actionhandler.h"
#include "fpdfsdk/javascript/ijs_runtime.h"
@@ -34,11 +38,19 @@ CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment(
UnderlyingDocumentType* pDoc,
FPDF_FORMFILLINFO* pFFinfo)
: m_pInfo(pFFinfo),
- m_pSDKDoc(new CPDFSDK_Document(pDoc, this)),
m_pUnderlyingDoc(pDoc),
- m_pSysHandler(new CFX_SystemHandler(this)) {}
+ m_pSysHandler(new CFX_SystemHandler(this)),
+ m_bChangeMask(FALSE),
+ m_bBeingDestroyed(FALSE) {}
CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() {
+ m_bBeingDestroyed = TRUE;
+
+ ClearAllFocusedAnnots();
+ for (auto& it : m_pageMap)
+ delete it.second;
+ m_pageMap.clear();
+
// |m_pAnnotHandlerMgr| will try to access |m_pFormFiller|
// when it cleans up. So, we must make sure it is cleaned up before
// |m_pFormFiller|.
@@ -562,3 +574,202 @@ void CPDFSDK_FormFillEnvironment::PageEvent(int iPageCount,
m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType);
}
#endif // PDF_ENABLE_XFA
+
+void CPDFSDK_FormFillEnvironment::ClearAllFocusedAnnots() {
+ for (auto& it : m_pageMap) {
+ if (it.second->IsValidSDKAnnot(GetFocusAnnot()))
+ KillFocusAnnot(0);
+ }
+}
+
+CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(
+ UnderlyingPageType* pUnderlyingPage,
+ bool ReNew) {
+ auto it = m_pageMap.find(pUnderlyingPage);
+ if (it != m_pageMap.end())
+ return it->second;
+
+ if (!ReNew)
+ return nullptr;
+
+ CPDFSDK_PageView* pPageView = new CPDFSDK_PageView(this, pUnderlyingPage);
+ m_pageMap[pUnderlyingPage] = pPageView;
+ // Delay to load all the annotations, to avoid endless loop.
+ pPageView->LoadFXAnnots();
+ return pPageView;
+}
+
+CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetCurrentView() {
+ UnderlyingPageType* pPage =
+ UnderlyingFromFPDFPage(GetCurrentPage(m_pUnderlyingDoc));
+ return pPage ? GetPageView(pPage, true) : nullptr;
+}
+
+CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(int nIndex) {
+ UnderlyingPageType* pTempPage =
+ UnderlyingFromFPDFPage(GetPage(m_pUnderlyingDoc, nIndex));
+ if (!pTempPage)
+ return nullptr;
+
+ auto it = m_pageMap.find(pTempPage);
+ return it != m_pageMap.end() ? it->second : nullptr;
+}
+
+void CPDFSDK_FormFillEnvironment::ProcJavascriptFun() {
+ CPDF_Document* pPDFDoc = GetPDFDocument();
+ CPDF_DocJSActions docJS(pPDFDoc);
+ int iCount = docJS.CountJSActions();
+ if (iCount < 1)
+ return;
+ for (int i = 0; i < iCount; i++) {
+ CFX_ByteString csJSName;
+ CPDF_Action jsAction = docJS.GetJSAction(i, csJSName);
+ if (GetActionHander()) {
+ GetActionHander()->DoAction_JavaScript(
+ jsAction, CFX_WideString::FromLocal(csJSName.AsStringC()), this);
+ }
+ }
+}
+
+FX_BOOL CPDFSDK_FormFillEnvironment::ProcOpenAction() {
+ if (!m_pUnderlyingDoc)
+ return FALSE;
+
+ CPDF_Dictionary* pRoot = GetPDFDocument()->GetRoot();
+ if (!pRoot)
+ return FALSE;
+
+ CPDF_Object* pOpenAction = pRoot->GetDictFor("OpenAction");
+ if (!pOpenAction)
+ pOpenAction = pRoot->GetArrayFor("OpenAction");
+
+ if (!pOpenAction)
+ return FALSE;
+
+ if (pOpenAction->IsArray())
+ return TRUE;
+
+ if (CPDF_Dictionary* pDict = pOpenAction->AsDictionary()) {
+ CPDF_Action action(pDict);
+ if (GetActionHander())
+ GetActionHander()->DoAction_DocOpen(action, this);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CPDFSDK_FormFillEnvironment::RemovePageView(
+ UnderlyingPageType* pUnderlyingPage) {
+ auto it = m_pageMap.find(pUnderlyingPage);
+ if (it == m_pageMap.end())
+ return;
+
+ CPDFSDK_PageView* pPageView = it->second;
+ if (pPageView->IsLocked() || pPageView->IsBeingDestroyed())
+ return;
+
+ // Mark the page view so we do not come into |RemovePageView| a second
+ // time while we're in the process of removing.
+ pPageView->SetBeingDestroyed();
+
+ // This must happen before we remove |pPageView| from the map because
+ // |KillFocusAnnot| can call into the |GetPage| method which will
+ // look for this page view in the map, if it doesn't find it a new one will
+ // be created. We then have two page views pointing to the same page and
+ // bad things happen.
+ if (pPageView->IsValidSDKAnnot(GetFocusAnnot()))
+ KillFocusAnnot(0);
+
+ // Remove the page from the map to make sure we don't accidentally attempt
+ // to use the |pPageView| while we're cleaning it up.
+ m_pageMap.erase(it);
+
+ delete pPageView;
+}
+
+UnderlyingPageType* CPDFSDK_FormFillEnvironment::GetPage(int nIndex) {
+ return UnderlyingFromFPDFPage(GetPage(m_pUnderlyingDoc, nIndex));
+}
+
+CPDFSDK_InterForm* CPDFSDK_FormFillEnvironment::GetInterForm() {
+ if (!m_pInterForm)
+ m_pInterForm = pdfium::MakeUnique<CPDFSDK_InterForm>(this);
+ return m_pInterForm.get();
+}
+
+void CPDFSDK_FormFillEnvironment::UpdateAllViews(CPDFSDK_PageView* pSender,
+ CPDFSDK_Annot* pAnnot) {
+ for (const auto& it : m_pageMap) {
+ CPDFSDK_PageView* pPageView = it.second;
+ if (pPageView != pSender)
+ pPageView->UpdateView(pAnnot);
+ }
+}
+
+FX_BOOL CPDFSDK_FormFillEnvironment::SetFocusAnnot(
+ CPDFSDK_Annot::ObservedPtr* pAnnot) {
+ if (m_bBeingDestroyed)
+ return FALSE;
+ if (m_pFocusAnnot == *pAnnot)
+ return TRUE;
+ if (m_pFocusAnnot && !KillFocusAnnot(0))
+ return FALSE;
+ if (!*pAnnot)
+ return FALSE;
+
+#ifdef PDF_ENABLE_XFA
+ CPDFSDK_Annot::ObservedPtr pLastFocusAnnot(m_pFocusAnnot.Get());
+#endif // PDF_ENABLE_XFA
+ CPDFSDK_PageView* pPageView = (*pAnnot)->GetPageView();
+ if (pPageView && pPageView->IsValid()) {
+ CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr();
+ if (!m_pFocusAnnot) {
+#ifdef PDF_ENABLE_XFA
+ if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot, &pLastFocusAnnot))
+ return FALSE;
+#endif // PDF_ENABLE_XFA
+ if (!pAnnotHandler->Annot_OnSetFocus(pAnnot, 0))
+ return FALSE;
+ if (!m_pFocusAnnot) {
+ m_pFocusAnnot.Reset(pAnnot->Get());
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+FX_BOOL CPDFSDK_FormFillEnvironment::KillFocusAnnot(uint32_t nFlag) {
+ if (m_pFocusAnnot) {
+ CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr();
+ CPDFSDK_Annot::ObservedPtr pFocusAnnot(m_pFocusAnnot.Get());
+ m_pFocusAnnot.Reset();
+
+#ifdef PDF_ENABLE_XFA
+ CPDFSDK_Annot::ObservedPtr pNull;
+ if (!pAnnotHandler->Annot_OnChangeFocus(&pNull, &pFocusAnnot))
+ return FALSE;
+#endif // PDF_ENABLE_XFA
+
+ if (pAnnotHandler->Annot_OnKillFocus(&pFocusAnnot, nFlag)) {
+ if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) {
+ CPDFSDK_Widget* pWidget =
+ static_cast<CPDFSDK_Widget*>(pFocusAnnot.Get());
+ int nFieldType = pWidget->GetFieldType();
+ if (FIELDTYPE_TEXTFIELD == nFieldType ||
+ FIELDTYPE_COMBOBOX == nFieldType) {
+ OnSetFieldInputFocus(nullptr, 0, FALSE);
+ }
+ }
+ if (!m_pFocusAnnot)
+ return TRUE;
+ } else {
+ m_pFocusAnnot.Reset(pFocusAnnot.Get());
+ }
+ }
+ return FALSE;
+}
+
+FX_BOOL CPDFSDK_FormFillEnvironment::GetPermissions(int nFlag) {
+ return GetPDFDocument()->GetUserPermissions() & nFlag;
+}