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;