From ce04a458828b45035dab46c13e14a1f0ae67a2b7 Mon Sep 17 00:00:00 2001 From: dsinclair Date: Wed, 7 Sep 2016 05:46:55 -0700 Subject: Add observer for BAAnnots from Javascript This Cl moves the observer code from the CPDFSDK_Widget up into the CPDFSDK_Annot base class and then adds a second observer for CPDFSDK_BAAnnot objects. This allows us to attach an observer to the Annot javascript class which will update its internal pointer to the BAAnnot if the BAAnnot is destroyed by the CPDFSDK_PageView being destroyed. BUG=chromium:642307 Review-Url: https://codereview.chromium.org/2306663002 --- fpdfsdk/cpdfsdk_annot.cpp | 32 +++++++++++++++++++++++++++++++- fpdfsdk/cpdfsdk_widget.cpp | 32 +------------------------------- fpdfsdk/include/cpdfsdk_annot.h | 14 ++++++++++++++ fpdfsdk/include/cpdfsdk_widget.h | 15 --------------- fpdfsdk/javascript/Annot.cpp | 35 ++++++++++++++++++++++++++++------- fpdfsdk/javascript/Annot.h | 5 ++++- fpdfsdk/javascript/Field.cpp | 7 ++++--- 7 files changed, 82 insertions(+), 58 deletions(-) diff --git a/fpdfsdk/cpdfsdk_annot.cpp b/fpdfsdk/cpdfsdk_annot.cpp index 59d8f24e82..353edaaaf9 100644 --- a/fpdfsdk/cpdfsdk_annot.cpp +++ b/fpdfsdk/cpdfsdk_annot.cpp @@ -9,6 +9,7 @@ #include #include "fpdfsdk/include/fsdk_mgr.h" +#include "third_party/base/stl_util.h" #ifdef PDF_ENABLE_XFA #include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h" @@ -21,10 +22,39 @@ const float kMinHeight = 1.0f; } // namespace +CPDFSDK_Annot::Observer::Observer(CPDFSDK_Annot** pWatchedPtr) + : m_pWatchedPtr(pWatchedPtr) { + (*m_pWatchedPtr)->AddObserver(this); +} + +CPDFSDK_Annot::Observer::~Observer() { + if (m_pWatchedPtr) + (*m_pWatchedPtr)->RemoveObserver(this); +} + +void CPDFSDK_Annot::Observer::OnAnnotDestroyed() { + ASSERT(m_pWatchedPtr); + *m_pWatchedPtr = nullptr; + m_pWatchedPtr = nullptr; +} + CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView) : m_pPageView(pPageView), m_bSelected(FALSE) {} -CPDFSDK_Annot::~CPDFSDK_Annot() {} +CPDFSDK_Annot::~CPDFSDK_Annot() { + for (auto* pObserver : m_Observers) + pObserver->OnAnnotDestroyed(); +} + +void CPDFSDK_Annot::AddObserver(Observer* pObserver) { + ASSERT(!pdfium::ContainsKey(m_Observers, pObserver)); + m_Observers.insert(pObserver); +} + +void CPDFSDK_Annot::RemoveObserver(Observer* pObserver) { + ASSERT(pdfium::ContainsKey(m_Observers, pObserver)); + m_Observers.erase(pObserver); +} #ifdef PDF_ENABLE_XFA diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp index 73ba23d076..2ddbccc28c 100644 --- a/fpdfsdk/cpdfsdk_widget.cpp +++ b/fpdfsdk/cpdfsdk_widget.cpp @@ -26,7 +26,6 @@ #include "fpdfsdk/include/fsdk_mgr.h" #include "fpdfsdk/pdfwindow/PWL_Edit.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" @@ -37,22 +36,6 @@ #include "xfa/fxfa/include/xfa_ffwidgethandler.h" #endif // PDF_ENABLE_XFA -CPDFSDK_Widget::Observer::Observer(CPDFSDK_Widget** pWatchedPtr) - : m_pWatchedPtr(pWatchedPtr) { - (*m_pWatchedPtr)->AddObserver(this); -} - -CPDFSDK_Widget::Observer::~Observer() { - if (m_pWatchedPtr) - (*m_pWatchedPtr)->RemoveObserver(this); -} - -void CPDFSDK_Widget::Observer::OnWidgetDestroyed() { - ASSERT(m_pWatchedPtr); - *m_pWatchedPtr = nullptr; - m_pWatchedPtr = nullptr; -} - CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm) @@ -68,20 +51,7 @@ CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, { } -CPDFSDK_Widget::~CPDFSDK_Widget() { - for (auto* pObserver : m_Observers) - pObserver->OnWidgetDestroyed(); -} - -void CPDFSDK_Widget::AddObserver(Observer* pObserver) { - ASSERT(!pdfium::ContainsKey(m_Observers, pObserver)); - m_Observers.insert(pObserver); -} - -void CPDFSDK_Widget::RemoveObserver(Observer* pObserver) { - ASSERT(pdfium::ContainsKey(m_Observers, pObserver)); - m_Observers.erase(pObserver); -} +CPDFSDK_Widget::~CPDFSDK_Widget() {} #ifdef PDF_ENABLE_XFA CXFA_FFWidget* CPDFSDK_Widget::GetMixXFAWidget() const { diff --git a/fpdfsdk/include/cpdfsdk_annot.h b/fpdfsdk/include/cpdfsdk_annot.h index 967226e9db..a43b8775db 100644 --- a/fpdfsdk/include/cpdfsdk_annot.h +++ b/fpdfsdk/include/cpdfsdk_annot.h @@ -23,9 +23,22 @@ class CPDFSDK_PageView; class CPDFSDK_Annot { public: + class Observer { + public: + explicit Observer(CPDFSDK_Annot** pWatchedPtr); + ~Observer(); + void OnAnnotDestroyed(); + + private: + CPDFSDK_Annot** m_pWatchedPtr; + }; + explicit CPDFSDK_Annot(CPDFSDK_PageView* pPageView); virtual ~CPDFSDK_Annot(); + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + #ifdef PDF_ENABLE_XFA virtual FX_BOOL IsXFAField(); virtual CXFA_FFWidget* GetXFAWidget() const; @@ -57,6 +70,7 @@ class CPDFSDK_Annot { void SetSelected(FX_BOOL bSelected); protected: + std::set m_Observers; CPDFSDK_PageView* m_pPageView; FX_BOOL m_bSelected; }; diff --git a/fpdfsdk/include/cpdfsdk_widget.h b/fpdfsdk/include/cpdfsdk_widget.h index 51116f9581..88692d553e 100644 --- a/fpdfsdk/include/cpdfsdk_widget.h +++ b/fpdfsdk/include/cpdfsdk_widget.h @@ -35,17 +35,6 @@ class CXFA_FFWidgetHandler; class CPDFSDK_Widget : public CPDFSDK_BAAnnot { public: - class Observer { - public: - explicit Observer(CPDFSDK_Widget** pWatchedPtr); - ~Observer(); - - void OnWidgetDestroyed(); - - private: - CPDFSDK_Widget** m_pWatchedPtr; - }; - #ifdef PDF_ENABLE_XFA CXFA_FFWidget* GetMixXFAWidget() const; CXFA_FFWidget* GetGroupMixXFAWidget(); @@ -75,9 +64,6 @@ class CPDFSDK_Widget : public CPDFSDK_BAAnnot { CPDFSDK_InterForm* pInterForm); ~CPDFSDK_Widget() override; - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - bool IsSignatureWidget() const override; CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT) override; FX_BOOL IsAppearanceValid() override; @@ -180,7 +166,6 @@ class CPDFSDK_Widget : public CPDFSDK_BAAnnot { FX_BOOL m_bAppModified; int32_t m_nAppAge; int32_t m_nValueAge; - std::set m_Observers; #ifdef PDF_ENABLE_XFA mutable CXFA_FFWidget* m_hMixXFAWidget; diff --git a/fpdfsdk/javascript/Annot.cpp b/fpdfsdk/javascript/Annot.cpp index a23d42f72a..ab84247baa 100644 --- a/fpdfsdk/javascript/Annot.cpp +++ b/fpdfsdk/javascript/Annot.cpp @@ -11,6 +11,14 @@ #include "fpdfsdk/javascript/JS_Value.h" #include "fpdfsdk/javascript/cjs_context.h" +namespace { + +CPDFSDK_BAAnnot* ToBAAnnot(CPDFSDK_Annot* annot) { + return static_cast(annot); +} + +} // namespace + BEGIN_JS_STATIC_CONST(CJS_Annot) END_JS_STATIC_CONST() @@ -32,8 +40,12 @@ Annot::~Annot() {} FX_BOOL Annot::hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { + CPDFSDK_BAAnnot* baAnnot = ToBAAnnot(m_pAnnot); + if (!baAnnot) + return FALSE; + if (vp.IsGetting()) { - CPDF_Annot* pPDFAnnot = m_BAAnnot->GetPDFAnnot(); + CPDF_Annot* pPDFAnnot = baAnnot->GetPDFAnnot(); vp << CPDF_Annot::IsAnnotationHidden(pPDFAnnot->GetAnnotDict()); return TRUE; } @@ -41,7 +53,7 @@ FX_BOOL Annot::hidden(IJS_Context* cc, bool bHidden; vp >> bHidden; - uint32_t flags = m_BAAnnot->GetFlags(); + uint32_t flags = baAnnot->GetFlags(); if (bHidden) { flags |= ANNOTFLAG_HIDDEN; flags |= ANNOTFLAG_INVISIBLE; @@ -53,21 +65,25 @@ FX_BOOL Annot::hidden(IJS_Context* cc, flags &= ~ANNOTFLAG_NOVIEW; flags |= ANNOTFLAG_PRINT; } - m_BAAnnot->SetFlags(flags); + baAnnot->SetFlags(flags); return TRUE; } FX_BOOL Annot::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { + CPDFSDK_BAAnnot* baAnnot = ToBAAnnot(m_pAnnot); + if (!baAnnot) + return FALSE; + if (vp.IsGetting()) { - vp << m_BAAnnot->GetAnnotName(); + vp << baAnnot->GetAnnotName(); return TRUE; } CFX_WideString annotName; vp >> annotName; - m_BAAnnot->SetAnnotName(annotName); + baAnnot->SetAnnotName(annotName); return TRUE; } @@ -80,10 +96,15 @@ FX_BOOL Annot::type(IJS_Context* cc, return FALSE; } - vp << CPDF_Annot::AnnotSubtypeToString(m_BAAnnot->GetAnnotSubtype()); + CPDFSDK_BAAnnot* baAnnot = ToBAAnnot(m_pAnnot); + if (!baAnnot) + return FALSE; + + vp << CPDF_Annot::AnnotSubtypeToString(baAnnot->GetAnnotSubtype()); return TRUE; } void Annot::SetSDKAnnot(CPDFSDK_BAAnnot* annot) { - m_BAAnnot = annot; + m_pAnnot = annot; + m_pObserver.reset(new CPDFSDK_Annot::Observer(&m_pAnnot)); } diff --git a/fpdfsdk/javascript/Annot.h b/fpdfsdk/javascript/Annot.h index b3ea292aed..be850350ae 100644 --- a/fpdfsdk/javascript/Annot.h +++ b/fpdfsdk/javascript/Annot.h @@ -7,6 +7,8 @@ #ifndef FPDFSDK_JAVASCRIPT_ANNOT_H_ #define FPDFSDK_JAVASCRIPT_ANNOT_H_ +#include + #include "fpdfsdk/include/cpdfsdk_baannot.h" #include "fpdfsdk/javascript/JS_Define.h" @@ -22,7 +24,8 @@ class Annot : public CJS_EmbedObj { void SetSDKAnnot(CPDFSDK_BAAnnot* annot); private: - CPDFSDK_BAAnnot* m_BAAnnot = nullptr; + CPDFSDK_Annot* m_pAnnot = nullptr; + std::unique_ptr m_pObserver; }; class CJS_Annot : public CJS_Object { diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp index 5c279d6b53..3f5e5e1b0f 100644 --- a/fpdfsdk/javascript/Field.cpp +++ b/fpdfsdk/javascript/Field.cpp @@ -267,11 +267,12 @@ void Field::UpdateFormField(CPDFSDK_Document* pDocument, if (bResetAP) { int nFieldType = pFormField->GetFieldType(); if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_TEXTFIELD) { - for (CPDFSDK_Widget* pWidget : widgets) { + for (CPDFSDK_Annot* pAnnot : widgets) { FX_BOOL bFormatted = FALSE; - CPDFSDK_Widget::Observer observer(&pWidget); + CPDFSDK_Widget* pWidget = static_cast(pAnnot); + CPDFSDK_Widget::Observer observer(&pAnnot); CFX_WideString sValue = pWidget->OnFormat(bFormatted); - if (pWidget) { + if (pAnnot) { pWidget->ResetAppearance(bFormatted ? sValue.c_str() : nullptr, FALSE); } -- cgit v1.2.3