|  | // Copyright 2014 The PDFium Authors | 
|  | // 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 | 
|  |  | 
|  | #ifndef FPDFSDK_FORMFILLER_CFFL_INTERACTIVEFORMFILLER_H_ | 
|  | #define FPDFSDK_FORMFILLER_CFFL_INTERACTIVEFORMFILLER_H_ | 
|  |  | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <utility> | 
|  |  | 
|  | #include "core/fxcrt/cfx_timer.h" | 
|  | #include "core/fxcrt/mask.h" | 
|  | #include "core/fxcrt/observed_ptr.h" | 
|  | #include "core/fxcrt/unowned_ptr.h" | 
|  | #include "fpdfsdk/cpdfsdk_annot.h" | 
|  | #include "fpdfsdk/pwl/ipwl_fillernotify.h" | 
|  | #include "public/fpdf_fwlevent.h" | 
|  |  | 
|  | class CFFL_FormField; | 
|  | class CPDFSDK_PageView; | 
|  | class CPDFSDK_Widget; | 
|  |  | 
|  | class CFFL_InteractiveFormFiller final : public IPWL_FillerNotify { | 
|  | public: | 
|  | class CallbackIface { | 
|  | public: | 
|  | virtual ~CallbackIface() = default; | 
|  |  | 
|  | virtual void OnSetFieldInputFocus(const WideString& text) = 0; | 
|  | virtual void OnCalculate(ObservedPtr<CPDFSDK_Annot>& pAnnot) = 0; | 
|  | virtual void OnFormat(ObservedPtr<CPDFSDK_Annot>& pAnnot) = 0; | 
|  | virtual void Invalidate(IPDF_Page* pPage, const FX_RECT& rect) = 0; | 
|  | virtual CPDFSDK_PageView* GetOrCreatePageView(IPDF_Page* pPage) = 0; | 
|  | virtual CPDFSDK_PageView* GetPageView(IPDF_Page* pPage) = 0; | 
|  | virtual CFX_Timer::HandlerIface* GetTimerHandler() = 0; | 
|  | virtual CPDFSDK_Annot* GetFocusAnnot() const = 0; | 
|  | virtual bool SetFocusAnnot(ObservedPtr<CPDFSDK_Annot>& pAnnot) = 0; | 
|  | virtual void InvalidateRect(CPDFSDK_Widget* pWidget, | 
|  | const CFX_FloatRect& rect) = 0; | 
|  | virtual void OutputSelectedRect(CFFL_FormField* pFormField, | 
|  | const CFX_FloatRect& rect) = 0; | 
|  | virtual bool IsSelectionImplemented() const = 0; | 
|  | virtual void SetCursor(CursorStyle nCursorStyle) = 0; | 
|  |  | 
|  | // See PDF Reference 1.7, table 3.20 for the permission bits. Returns true | 
|  | // if any bit in |flags| is set. | 
|  | virtual bool HasPermissions(uint32_t flags) const = 0; | 
|  | virtual void OnChange() = 0; | 
|  | }; | 
|  |  | 
|  | explicit CFFL_InteractiveFormFiller(CallbackIface* pCallbackIface); | 
|  | ~CFFL_InteractiveFormFiller() override; | 
|  |  | 
|  | bool Annot_HitTest(const CPDFSDK_Widget* pWidget, const CFX_PointF& point); | 
|  | FX_RECT GetViewBBox(const CPDFSDK_PageView* pPageView, | 
|  | CPDFSDK_Widget* pWidget); | 
|  |  | 
|  | void OnDraw(CPDFSDK_PageView* pPageView, | 
|  | CPDFSDK_Widget* pWidget, | 
|  | CFX_RenderDevice* pDevice, | 
|  | const CFX_Matrix& mtUser2Device); | 
|  | void OnDelete(CPDFSDK_Widget* pWidget); | 
|  |  | 
|  | void OnMouseEnter(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | void OnMouseExit(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | bool OnLButtonDown(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlags, | 
|  | const CFX_PointF& point); | 
|  | bool OnLButtonUp(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlags, | 
|  | const CFX_PointF& point); | 
|  | bool OnLButtonDblClk(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlags, | 
|  | const CFX_PointF& point); | 
|  | bool OnMouseMove(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlags, | 
|  | const CFX_PointF& point); | 
|  | bool OnMouseWheel(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlags, | 
|  | const CFX_PointF& point, | 
|  | const CFX_Vector& delta); | 
|  | bool OnRButtonDown(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlags, | 
|  | const CFX_PointF& point); | 
|  | bool OnRButtonUp(CPDFSDK_PageView* pPageView, | 
|  | ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlags, | 
|  | const CFX_PointF& point); | 
|  |  | 
|  | bool OnKeyDown(CPDFSDK_Widget* pWidget, | 
|  | FWL_VKEYCODE nKeyCode, | 
|  | Mask<FWL_EVENTFLAG> nFlags); | 
|  | bool OnChar(CPDFSDK_Widget* pWidget, | 
|  | uint32_t nChar, | 
|  | Mask<FWL_EVENTFLAG> nFlags); | 
|  |  | 
|  | bool OnSetFocus(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | bool OnKillFocus(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  |  | 
|  | // Wrapper methods for CallbackIface | 
|  | void OnSetFieldInputFocus(const WideString& text); | 
|  | void Invalidate(IPDF_Page* pPage, const FX_RECT& rect); | 
|  | CPDFSDK_PageView* GetOrCreatePageView(IPDF_Page* pPage); | 
|  | CPDFSDK_PageView* GetPageView(IPDF_Page* pPage); | 
|  | CFX_Timer::HandlerIface* GetTimerHandler(); | 
|  | void OnChange(); | 
|  |  | 
|  | CFFL_FormField* GetFormFieldForTesting(CPDFSDK_Widget* pAnnot) { | 
|  | return GetFormField(pAnnot); | 
|  | } | 
|  |  | 
|  | WideString GetText(CPDFSDK_Widget* pWidget); | 
|  | WideString GetSelectedText(CPDFSDK_Widget* pWidget); | 
|  | void ReplaceAndKeepSelection(CPDFSDK_Widget* pWidget, const WideString& text); | 
|  | void ReplaceSelection(CPDFSDK_Widget* pWidget, const WideString& text); | 
|  | bool SelectAllText(CPDFSDK_Widget* pWidget); | 
|  |  | 
|  | bool CanUndo(CPDFSDK_Widget* pWidget); | 
|  | bool CanRedo(CPDFSDK_Widget* pWidget); | 
|  | bool Undo(CPDFSDK_Widget* pWidget); | 
|  | bool Redo(CPDFSDK_Widget* pWidget); | 
|  |  | 
|  | static bool IsVisible(CPDFSDK_Widget* pWidget); | 
|  | static bool IsReadOnly(CPDFSDK_Widget* pWidget); | 
|  | static bool IsValidAnnot(const CPDFSDK_PageView* pPageView, | 
|  | CPDFSDK_Widget* pWidget); | 
|  |  | 
|  | bool OnKeyStrokeCommit(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | const CPDFSDK_PageView* pPageView, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | bool OnValidate(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | const CPDFSDK_PageView* pPageView, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | void OnCalculate(ObservedPtr<CPDFSDK_Widget>& pWidget); | 
|  | void OnFormat(ObservedPtr<CPDFSDK_Widget>& pWidget); | 
|  | bool OnButtonUp(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | const CPDFSDK_PageView* pPageView, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  |  | 
|  | bool SetIndexSelected(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | int index, | 
|  | bool selected); | 
|  | bool IsIndexSelected(ObservedPtr<CPDFSDK_Widget>& pWidget, int index); | 
|  |  | 
|  | private: | 
|  | using WidgetToFormFillerMap = | 
|  | std::map<CPDFSDK_Widget*, std::unique_ptr<CFFL_FormField>>; | 
|  |  | 
|  | // IPWL_FillerNotify: | 
|  | void InvalidateRect(PerWindowData* pWidgetData, | 
|  | const CFX_FloatRect& rect) override; | 
|  | void OutputSelectedRect(PerWindowData* pWidgetData, | 
|  | const CFX_FloatRect& rect) override; | 
|  | bool IsSelectionImplemented() const override; | 
|  | void SetCursor(CursorStyle nCursorStyle) override; | 
|  | void QueryWherePopup(const PerWindowData* pAttached, | 
|  | float fPopupMin, | 
|  | float fPopupMax, | 
|  | bool* bBottom, | 
|  | float* fPopupRet) override; | 
|  | // Returns {bRC, bExit}. | 
|  | std::pair<bool, bool> OnBeforeKeyStroke(const PerWindowData* pAttached, | 
|  | WideString& strChange, | 
|  | const WideString& strChangeEx, | 
|  | int nSelStart, | 
|  | int nSelEnd, | 
|  | bool bKeyDown, | 
|  | Mask<FWL_EVENTFLAG> nFlag) override; | 
|  | bool OnPopupPreOpen(const PerWindowData* pAttached, | 
|  | Mask<FWL_EVENTFLAG> nFlag) override; | 
|  | bool OnPopupPostOpen(const PerWindowData* pAttached, | 
|  | Mask<FWL_EVENTFLAG> nFlag) override; | 
|  |  | 
|  | #ifdef PDF_ENABLE_XFA | 
|  | void SetFocusAnnotTab(CPDFSDK_Widget* pWidget, bool bSameField, bool bNext); | 
|  | bool OnClick(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | const CPDFSDK_PageView* pPageView, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | bool OnFull(ObservedPtr<CPDFSDK_Widget>& pAnnot, | 
|  | const CPDFSDK_PageView* pPageView, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | bool OnPreOpen(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | const CPDFSDK_PageView* pPageView, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | bool OnPostOpen(ObservedPtr<CPDFSDK_Widget>& pWidget, | 
|  | const CPDFSDK_PageView* pPageView, | 
|  | Mask<FWL_EVENTFLAG> nFlag); | 
|  | #endif  // PDF_ENABLE_XFA | 
|  |  | 
|  | bool IsFillingAllowed(CPDFSDK_Widget* pWidget) const; | 
|  | CFFL_FormField* GetFormField(CPDFSDK_Widget* pWidget); | 
|  | CFFL_FormField* GetOrCreateFormField(CPDFSDK_Widget* pWidget); | 
|  | void UnregisterFormField(CPDFSDK_Widget* pWidget); | 
|  |  | 
|  | UnownedPtr<CallbackIface> const m_pCallbackIface; | 
|  | WidgetToFormFillerMap m_Map; | 
|  | bool m_bNotifying = false; | 
|  | }; | 
|  |  | 
|  | #endif  // FPDFSDK_FORMFILLER_CFFL_INTERACTIVEFORMFILLER_H_ |