Initialize widget handlers from topmost fpdfsdk.
In turn, removes some knowledge of XFA from fpdfsdk/cpdfsdk_*.cpp.
In some ideal world, only fpdf_* files would be including fpdfxfa/
headers.
There is a small loss of const, as the objects must be created
before the formfillenvironment, and hence can't have const
members pointing back to it.
Change-Id: I2edf2bfc952b2e361e57b180e3edf5068f165b38
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/59577
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
index 48daf0f..eed1df6 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
@@ -29,19 +29,26 @@
#endif // PDF_ENABLE_XFA
CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(
- CPDFSDK_FormFillEnvironment* pFormFillEnv)
- : m_pBAAnnotHandler(pdfium::MakeUnique<CPDFSDK_BAAnnotHandler>()),
- m_pWidgetHandler(pdfium::MakeUnique<CPDFSDK_WidgetHandler>(pFormFillEnv))
-#ifdef PDF_ENABLE_XFA
- ,
- m_pXFAWidgetHandler(
- pdfium::MakeUnique<CPDFXFA_WidgetHandler>(pFormFillEnv))
-#endif // PDF_ENABLE_XFA
-{
+ std::unique_ptr<CPDFSDK_BAAnnotHandler> pBAAnnotHandler,
+ std::unique_ptr<CPDFSDK_WidgetHandler> pWidgetHandler,
+ std::unique_ptr<IPDFSDK_AnnotHandler> pXFAWidgetHandler)
+ : m_pBAAnnotHandler(std::move(pBAAnnotHandler)),
+ m_pWidgetHandler(std::move(pWidgetHandler)),
+ m_pXFAWidgetHandler(std::move(pXFAWidgetHandler)) {
+ ASSERT(m_pBAAnnotHandler);
+ ASSERT(m_pWidgetHandler);
}
CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() = default;
+void CPDFSDK_AnnotHandlerMgr::SetFormFillEnv(
+ CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+ m_pBAAnnotHandler->SetFormFillEnvironment(pFormFillEnv);
+ m_pWidgetHandler->SetFormFillEnvironment(pFormFillEnv);
+ if (m_pXFAWidgetHandler)
+ m_pXFAWidgetHandler->SetFormFillEnvironment(pFormFillEnv);
+}
+
CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot* pAnnot,
CPDFSDK_PageView* pPageView) {
ASSERT(pPageView);
@@ -55,7 +62,8 @@
CPDFSDK_PageView* pPageView) {
ASSERT(pAnnot);
ASSERT(pPageView);
- return m_pXFAWidgetHandler->NewAnnotForXFA(pAnnot, pPageView);
+ return static_cast<CPDFXFA_WidgetHandler*>(m_pXFAWidgetHandler.get())
+ ->NewAnnotForXFA(pAnnot, pPageView);
}
#endif // PDF_ENABLE_XFA
@@ -280,7 +288,9 @@
ObservedPtr<CPDFSDK_Annot>* pKillAnnot) {
bool bXFA = (*pSetAnnot && (*pSetAnnot)->GetXFAWidget()) ||
(*pKillAnnot && (*pKillAnnot)->GetXFAWidget());
- return !bXFA || m_pXFAWidgetHandler->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
+
+ return !bXFA || static_cast<CPDFXFA_WidgetHandler*>(m_pXFAWidgetHandler.get())
+ ->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
}
#endif // PDF_ENABLE_XFA
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.h b/fpdfsdk/cpdfsdk_annothandlermgr.h
index 5c3c73a..5d70f00 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.h
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.h
@@ -22,15 +22,20 @@
class IPDFSDK_AnnotHandler;
#ifdef PDF_ENABLE_XFA
-class CPDFXFA_WidgetHandler;
class CXFA_FFWidget;
#endif // PDF_ENABLE_XFA
class CPDFSDK_AnnotHandlerMgr {
public:
- explicit CPDFSDK_AnnotHandlerMgr(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+ CPDFSDK_AnnotHandlerMgr(
+ std::unique_ptr<CPDFSDK_BAAnnotHandler> pBAAnnotHandler,
+ std::unique_ptr<CPDFSDK_WidgetHandler> pWidgetHandler,
+ std::unique_ptr<IPDFSDK_AnnotHandler> pXFAWidgetHandler);
+
~CPDFSDK_AnnotHandlerMgr();
+ void SetFormFillEnv(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView);
#ifdef PDF_ENABLE_XFA
CPDFSDK_Annot* NewXFAAnnot(CXFA_FFWidget* pAnnot,
@@ -116,11 +121,11 @@
CPDF_Annot::Subtype nAnnotSubtype) const;
CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pSDKAnnot, bool bNext);
+ // |m_pBAAnnotHandler| and |m_pWidgetHandler| are always present, but
+ // |m_pXFAWidgetHandler| is only present in XFA mode.
std::unique_ptr<CPDFSDK_BAAnnotHandler> const m_pBAAnnotHandler;
std::unique_ptr<CPDFSDK_WidgetHandler> const m_pWidgetHandler;
-#ifdef PDF_ENABLE_XFA
- std::unique_ptr<CPDFXFA_WidgetHandler> const m_pXFAWidgetHandler;
-#endif // PDF_ENABLE_XFA
+ std::unique_ptr<IPDFSDK_AnnotHandler> const m_pXFAWidgetHandler;
};
#endif // FPDFSDK_CPDFSDK_ANNOTHANDLERMGR_H_
diff --git a/fpdfsdk/cpdfsdk_baannothandler.cpp b/fpdfsdk/cpdfsdk_baannothandler.cpp
index 1b6e31b..39b6f31 100644
--- a/fpdfsdk/cpdfsdk_baannothandler.cpp
+++ b/fpdfsdk/cpdfsdk_baannothandler.cpp
@@ -38,6 +38,11 @@
CPDFSDK_BAAnnotHandler::~CPDFSDK_BAAnnotHandler() {}
+void CPDFSDK_BAAnnotHandler::SetFormFillEnvironment(
+ CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+ // CPDFSDK_BAAnnotHandler does not need it.
+}
+
bool CPDFSDK_BAAnnotHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
return false;
}
diff --git a/fpdfsdk/cpdfsdk_baannothandler.h b/fpdfsdk/cpdfsdk_baannothandler.h
index 4fc094a..295bf0d 100644
--- a/fpdfsdk/cpdfsdk_baannothandler.h
+++ b/fpdfsdk/cpdfsdk_baannothandler.h
@@ -25,6 +25,9 @@
CPDFSDK_BAAnnotHandler();
~CPDFSDK_BAAnnotHandler() override;
+ // IPDFSDK_AnnotHandler:
+ void SetFormFillEnvironment(
+ CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
bool CanAnswer(CPDFSDK_Annot* pAnnot) override;
CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) override;
void ReleaseAnnot(std::unique_ptr<CPDFSDK_Annot> pAnnot) override;
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
index 634fd70..3c1dae5 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.cpp
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
@@ -34,9 +34,13 @@
CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment(
CPDF_Document* pDoc,
- FPDF_FORMFILLINFO* pFFinfo)
- : m_pInfo(pFFinfo), m_pCPDFDoc(pDoc) {
+ FPDF_FORMFILLINFO* pFFinfo,
+ std::unique_ptr<CPDFSDK_AnnotHandlerMgr> pHandlerMgr)
+ : m_pInfo(pFFinfo),
+ m_pCPDFDoc(pDoc),
+ m_pAnnotHandlerMgr(std::move(pHandlerMgr)) {
ASSERT(m_pCPDFDoc);
+ m_pAnnotHandlerMgr->SetFormFillEnv(this);
}
CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() {
@@ -316,8 +320,6 @@
}
CPDFSDK_AnnotHandlerMgr* CPDFSDK_FormFillEnvironment::GetAnnotHandlerMgr() {
- if (!m_pAnnotHandlerMgr)
- m_pAnnotHandlerMgr = pdfium::MakeUnique<CPDFSDK_AnnotHandlerMgr>(this);
return m_pAnnotHandlerMgr.get();
}
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.h b/fpdfsdk/cpdfsdk_formfillenvironment.h
index 130e208..1b47e22 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.h
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.h
@@ -46,7 +46,11 @@
public TimerHandlerIface,
public IPWL_SystemHandler {
public:
- CPDFSDK_FormFillEnvironment(CPDF_Document* pDoc, FPDF_FORMFILLINFO* pFFinfo);
+ CPDFSDK_FormFillEnvironment(
+ CPDF_Document* pDoc,
+ FPDF_FORMFILLINFO* pFFinfo,
+ std::unique_ptr<CPDFSDK_AnnotHandlerMgr> pHandlerMgr);
+
~CPDFSDK_FormFillEnvironment() override;
// TimerHandlerIface:
@@ -202,9 +206,10 @@
FPDF_FORMFILLINFO* GetFormFillInfo() const { return m_pInfo; }
void SubmitForm(pdfium::span<uint8_t> form_data, const WideString& URL);
+ CPDFSDK_AnnotHandlerMgr* GetAnnotHandlerMgr(); // Always present.
+
// Creates if not present.
CFFL_InteractiveFormFiller* GetInteractiveFormFiller();
- CPDFSDK_AnnotHandlerMgr* GetAnnotHandlerMgr(); // Creates if not present.
IJS_Runtime* GetIJSRuntime(); // Creates if not present.
CPDFSDK_ActionHandler* GetActionHandler(); // Creates if not present.
CPDFSDK_InteractiveForm* GetInteractiveForm(); // Creates if not present.
@@ -213,13 +218,13 @@
IPDF_Page* GetPage(int nIndex);
FPDF_FORMFILLINFO* const m_pInfo;
- std::unique_ptr<CPDFSDK_AnnotHandlerMgr> m_pAnnotHandlerMgr;
std::unique_ptr<CPDFSDK_ActionHandler> m_pActionHandler;
std::unique_ptr<IJS_Runtime> m_pIJSRuntime;
std::map<IPDF_Page*, std::unique_ptr<CPDFSDK_PageView>> m_PageMap;
std::unique_ptr<CPDFSDK_InteractiveForm> m_pInteractiveForm;
ObservedPtr<CPDFSDK_Annot> m_pFocusAnnot;
UnownedPtr<CPDF_Document> const m_pCPDFDoc;
+ std::unique_ptr<CPDFSDK_AnnotHandlerMgr> m_pAnnotHandlerMgr;
std::unique_ptr<CFFL_InteractiveFormFiller> m_pFormFiller;
bool m_bChangeMask = false;
bool m_bBeingDestroyed = false;
diff --git a/fpdfsdk/cpdfsdk_pageview.h b/fpdfsdk/cpdfsdk_pageview.h
index d534902..3b04dfb 100644
--- a/fpdfsdk/cpdfsdk_pageview.h
+++ b/fpdfsdk/cpdfsdk_pageview.h
@@ -19,6 +19,7 @@
class CFX_RenderDevice;
class CPDF_AnnotList;
class CPDF_RenderOptions;
+class CPDFSDK_FormFillEnvironment;
class CPDFSDK_PageView final : public CPDF_Page::View {
public:
diff --git a/fpdfsdk/cpdfsdk_widgethandler.cpp b/fpdfsdk/cpdfsdk_widgethandler.cpp
index e1c5c9c..1e4462d 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.cpp
+++ b/fpdfsdk/cpdfsdk_widgethandler.cpp
@@ -20,16 +20,16 @@
#include "fpdfsdk/cpdfsdk_widget.h"
#include "fpdfsdk/formfiller/cffl_formfiller.h"
-CPDFSDK_WidgetHandler::CPDFSDK_WidgetHandler(
- CPDFSDK_FormFillEnvironment* pFormFillEnv)
- : m_pFormFillEnv(pFormFillEnv),
- m_pFormFiller(pFormFillEnv->GetInteractiveFormFiller()) {
- ASSERT(m_pFormFillEnv);
- ASSERT(m_pFormFiller);
-}
+CPDFSDK_WidgetHandler::CPDFSDK_WidgetHandler() = default;
CPDFSDK_WidgetHandler::~CPDFSDK_WidgetHandler() = default;
+void CPDFSDK_WidgetHandler::SetFormFillEnvironment(
+ CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+ m_pFormFillEnv = pFormFillEnv;
+ m_pFormFiller = m_pFormFillEnv->GetInteractiveFormFiller();
+}
+
bool CPDFSDK_WidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot);
if (pWidget->IsSignatureWidget())
diff --git a/fpdfsdk/cpdfsdk_widgethandler.h b/fpdfsdk/cpdfsdk_widgethandler.h
index 9c0c1e3..fa2ac94 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.h
+++ b/fpdfsdk/cpdfsdk_widgethandler.h
@@ -23,9 +23,11 @@
class CPDFSDK_WidgetHandler final : public IPDFSDK_AnnotHandler {
public:
- explicit CPDFSDK_WidgetHandler(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+ CPDFSDK_WidgetHandler();
~CPDFSDK_WidgetHandler() override;
+ void SetFormFillEnvironment(
+ CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
bool CanAnswer(CPDFSDK_Annot* pAnnot) override;
CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) override;
void ReleaseAnnot(std::unique_ptr<CPDFSDK_Annot> pAnnot) override;
@@ -98,8 +100,8 @@
bool IsIndexSelected(ObservedPtr<CPDFSDK_Annot>* pAnnot, int index) override;
private:
- UnownedPtr<CPDFSDK_FormFillEnvironment> const m_pFormFillEnv;
- UnownedPtr<CFFL_InteractiveFormFiller> const m_pFormFiller;
+ UnownedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
+ UnownedPtr<CFFL_InteractiveFormFiller> m_pFormFiller;
};
#endif // FPDFSDK_CPDFSDK_WIDGETHANDLER_H_
diff --git a/fpdfsdk/fpdf_formfill.cpp b/fpdfsdk/fpdf_formfill.cpp
index d260754..35685c8 100644
--- a/fpdfsdk/fpdf_formfill.cpp
+++ b/fpdfsdk/fpdf_formfill.cpp
@@ -7,6 +7,7 @@
#include "public/fpdf_formfill.h"
#include <memory>
+#include <utility>
#include <vector>
#include "core/fpdfapi/page/cpdf_occontext.h"
@@ -19,16 +20,19 @@
#include "core/fpdfdoc/cpdf_interactiveform.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "fpdfsdk/cpdfsdk_actionhandler.h"
+#include "fpdfsdk/cpdfsdk_baannothandler.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widgethandler.h"
#include "public/fpdfview.h"
#include "third_party/base/ptr_util.h"
#ifdef PDF_ENABLE_XFA
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.h"
static_assert(static_cast<int>(AlertButton::kDefault) ==
JSPLATFORM_ALERT_BUTTON_DEFAULT,
@@ -304,8 +308,16 @@
}
#endif
- auto pFormFillEnv =
- pdfium::MakeUnique<CPDFSDK_FormFillEnvironment>(pDocument, formInfo);
+ std::unique_ptr<IPDFSDK_AnnotHandler> pXFAHandler;
+#ifdef PDF_ENABLE_XFA
+ pXFAHandler = pdfium::MakeUnique<CPDFXFA_WidgetHandler>();
+#endif // PDF_ENABLE_XFA
+
+ auto pFormFillEnv = pdfium::MakeUnique<CPDFSDK_FormFillEnvironment>(
+ pDocument, formInfo,
+ pdfium::MakeUnique<CPDFSDK_AnnotHandlerMgr>(
+ pdfium::MakeUnique<CPDFSDK_BAAnnotHandler>(),
+ pdfium::MakeUnique<CPDFSDK_WidgetHandler>(), std::move(pXFAHandler)));
#ifdef PDF_ENABLE_XFA
if (pContext)
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.cpp
index 4638cd8..7b7c53b 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.cpp
@@ -200,11 +200,14 @@
#undef CHECK_FWL_VKEY_ENUM____
-CPDFXFA_WidgetHandler::CPDFXFA_WidgetHandler(
- CPDFSDK_FormFillEnvironment* pFormFillEnv)
- : m_pFormFillEnv(pFormFillEnv) {}
+CPDFXFA_WidgetHandler::CPDFXFA_WidgetHandler() = default;
-CPDFXFA_WidgetHandler::~CPDFXFA_WidgetHandler() {}
+CPDFXFA_WidgetHandler::~CPDFXFA_WidgetHandler() = default;
+
+void CPDFXFA_WidgetHandler::SetFormFillEnvironment(
+ CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+ m_pFormFillEnv = pFormFillEnv;
+}
bool CPDFXFA_WidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
return !!pAnnot->GetXFAWidget();
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.h b/fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.h
index 5083bec..9bb5891 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.h
@@ -24,10 +24,12 @@
class CPDFXFA_WidgetHandler final : public IPDFSDK_AnnotHandler {
public:
- explicit CPDFXFA_WidgetHandler(CPDFSDK_FormFillEnvironment* pApp);
+ CPDFXFA_WidgetHandler();
~CPDFXFA_WidgetHandler() override;
// IPDFSDK_AnnotHandler:
+ void SetFormFillEnvironment(
+ CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
bool CanAnswer(CPDFSDK_Annot* pAnnot) override;
CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) override;
void ReleaseAnnot(std::unique_ptr<CPDFSDK_Annot> pAnnot) override;
@@ -106,7 +108,7 @@
CXFA_FFWidgetHandler* GetXFAWidgetHandler(CPDFSDK_Annot* pAnnot);
uint32_t GetFWLFlags(uint32_t dwFlag);
- UnownedPtr<CPDFSDK_FormFillEnvironment> const m_pFormFillEnv;
+ UnownedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
};
#endif // FPDFSDK_FPDFXFA_CPDFXFA_WIDGETHANDLER_H_
diff --git a/fpdfsdk/ipdfsdk_annothandler.h b/fpdfsdk/ipdfsdk_annothandler.h
index 26de54d..24b6ff0 100644
--- a/fpdfsdk/ipdfsdk_annothandler.h
+++ b/fpdfsdk/ipdfsdk_annothandler.h
@@ -15,12 +15,15 @@
class CFX_Matrix;
class CFX_RenderDevice;
class CPDF_Annot;
+class CPDFSDK_FormFillEnvironment;
class CPDFSDK_PageView;
class IPDFSDK_AnnotHandler {
public:
virtual ~IPDFSDK_AnnotHandler() = default;
+ virtual void SetFormFillEnvironment(
+ CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
virtual bool CanAnswer(CPDFSDK_Annot* pAnnot) = 0;
virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot,
CPDFSDK_PageView* pPage) = 0;