blob: bbf757d813c95315eed035b245e3d56dc8eac719 [file] [log] [blame]
// 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_