1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "fpdfsdk/cpdfsdk_annothandlermgr.h"
8
9 #include "core/fpdfapi/parser/cpdf_number.h"
10 #include "core/fpdfapi/parser/cpdf_string.h"
11 #include "core/fpdfdoc/cpdf_annot.h"
12 #include "fpdfsdk/cba_annotiterator.h"
13 #include "fpdfsdk/cpdfsdk_annot.h"
14 #include "fpdfsdk/cpdfsdk_baannot.h"
15 #include "fpdfsdk/cpdfsdk_baannothandler.h"
16 #include "fpdfsdk/cpdfsdk_datetime.h"
17 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
18 #include "fpdfsdk/cpdfsdk_pageview.h"
19 #include "fpdfsdk/cpdfsdk_widgethandler.h"
20
21 #ifdef PDF_ENABLE_XFA
22 #include "fpdfsdk/cpdfsdk_xfawidgethandler.h"
23 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
24 #include "xfa/fxfa/xfa_ffpageview.h"
25 #include "xfa/fxfa/xfa_ffwidget.h"
26 #endif // PDF_ENABLE_XFA
27
CPDFSDK_AnnotHandlerMgr(CPDFSDK_FormFillEnvironment * pFormFillEnv)28 CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(
29 CPDFSDK_FormFillEnvironment* pFormFillEnv)
30 : m_pBAAnnotHandler(new CPDFSDK_BAAnnotHandler()),
31 m_pWidgetHandler(new CPDFSDK_WidgetHandler(pFormFillEnv)),
32 #ifdef PDF_ENABLE_XFA
33 m_pXFAWidgetHandler(new CPDFSDK_XFAWidgetHandler(pFormFillEnv)),
34 #endif // PDF_ENABLE_XFA
35 m_pFormFillEnv(pFormFillEnv) {
36 m_pWidgetHandler->SetFormFiller(m_pFormFillEnv->GetInteractiveFormFiller());
37 }
38
~CPDFSDK_AnnotHandlerMgr()39 CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() {}
40
NewAnnot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPageView)41 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot* pAnnot,
42 CPDFSDK_PageView* pPageView) {
43 ASSERT(pPageView);
44 return GetAnnotHandler(pAnnot->GetSubtype())->NewAnnot(pAnnot, pPageView);
45 }
46
47 #ifdef PDF_ENABLE_XFA
NewAnnot(CXFA_FFWidget * pAnnot,CPDFSDK_PageView * pPageView)48 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CXFA_FFWidget* pAnnot,
49 CPDFSDK_PageView* pPageView) {
50 ASSERT(pAnnot);
51 ASSERT(pPageView);
52
53 return GetAnnotHandler(CPDF_Annot::Subtype::XFAWIDGET)
54 ->NewAnnot(pAnnot, pPageView);
55 }
56 #endif // PDF_ENABLE_XFA
57
ReleaseAnnot(CPDFSDK_Annot * pAnnot)58 void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
59 IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
60 pAnnotHandler->ReleaseAnnot(pAnnot);
61 }
62
Annot_OnCreate(CPDFSDK_Annot * pAnnot)63 void CPDFSDK_AnnotHandlerMgr::Annot_OnCreate(CPDFSDK_Annot* pAnnot) {
64 CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
65
66 CPDFSDK_DateTime curTime;
67 pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
68 "M", curTime.ToPDFDateTimeString(), false);
69 pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F", 0);
70 }
71
Annot_OnLoad(CPDFSDK_Annot * pAnnot)72 void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) {
73 ASSERT(pAnnot);
74 GetAnnotHandler(pAnnot)->OnLoad(pAnnot);
75 }
76
GetAnnotHandler(CPDFSDK_Annot * pAnnot) const77 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
78 CPDFSDK_Annot* pAnnot) const {
79 return GetAnnotHandler(pAnnot->GetAnnotSubtype());
80 }
81
GetAnnotHandler(CPDF_Annot::Subtype nAnnotSubtype) const82 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
83 CPDF_Annot::Subtype nAnnotSubtype) const {
84 if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET)
85 return m_pWidgetHandler.get();
86
87 #ifdef PDF_ENABLE_XFA
88 if (nAnnotSubtype == CPDF_Annot::Subtype::XFAWIDGET)
89 return m_pXFAWidgetHandler.get();
90 #endif // PDF_ENABLE_XFA
91
92 return m_pBAAnnotHandler.get();
93 }
94
Annot_OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device,bool bDrawAnnots)95 void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView,
96 CPDFSDK_Annot* pAnnot,
97 CFX_RenderDevice* pDevice,
98 CFX_Matrix* pUser2Device,
99 bool bDrawAnnots) {
100 ASSERT(pAnnot);
101 GetAnnotHandler(pAnnot)->OnDraw(pPageView, pAnnot, pDevice, pUser2Device,
102 bDrawAnnots);
103 }
104
Annot_OnLButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)105 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown(
106 CPDFSDK_PageView* pPageView,
107 CPDFSDK_Annot::ObservedPtr* pAnnot,
108 uint32_t nFlags,
109 const CFX_PointF& point) {
110 ASSERT(*pAnnot);
111 return GetAnnotHandler(pAnnot->Get())
112 ->OnLButtonDown(pPageView, pAnnot, nFlags, point);
113 }
114
Annot_OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)115 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp(
116 CPDFSDK_PageView* pPageView,
117 CPDFSDK_Annot::ObservedPtr* pAnnot,
118 uint32_t nFlags,
119 const CFX_PointF& point) {
120 ASSERT(*pAnnot);
121 return GetAnnotHandler(pAnnot->Get())
122 ->OnLButtonUp(pPageView, pAnnot, nFlags, point);
123 }
124
Annot_OnLButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)125 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk(
126 CPDFSDK_PageView* pPageView,
127 CPDFSDK_Annot::ObservedPtr* pAnnot,
128 uint32_t nFlags,
129 const CFX_PointF& point) {
130 ASSERT(*pAnnot);
131 return GetAnnotHandler(pAnnot->Get())
132 ->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
133 }
134
Annot_OnMouseMove(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)135 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove(
136 CPDFSDK_PageView* pPageView,
137 CPDFSDK_Annot::ObservedPtr* pAnnot,
138 uint32_t nFlags,
139 const CFX_PointF& point) {
140 ASSERT(*pAnnot);
141 return GetAnnotHandler(pAnnot->Get())
142 ->OnMouseMove(pPageView, pAnnot, nFlags, point);
143 }
144
Annot_OnMouseWheel(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)145 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel(
146 CPDFSDK_PageView* pPageView,
147 CPDFSDK_Annot::ObservedPtr* pAnnot,
148 uint32_t nFlags,
149 short zDelta,
150 const CFX_PointF& point) {
151 ASSERT(*pAnnot);
152 return GetAnnotHandler(pAnnot->Get())
153 ->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
154 }
155
Annot_OnRButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)156 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown(
157 CPDFSDK_PageView* pPageView,
158 CPDFSDK_Annot::ObservedPtr* pAnnot,
159 uint32_t nFlags,
160 const CFX_PointF& point) {
161 ASSERT(*pAnnot);
162 return GetAnnotHandler(pAnnot->Get())
163 ->OnRButtonDown(pPageView, pAnnot, nFlags, point);
164 }
165
Annot_OnRButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)166 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp(
167 CPDFSDK_PageView* pPageView,
168 CPDFSDK_Annot::ObservedPtr* pAnnot,
169 uint32_t nFlags,
170 const CFX_PointF& point) {
171 ASSERT(*pAnnot);
172 return GetAnnotHandler(pAnnot->Get())
173 ->OnRButtonUp(pPageView, pAnnot, nFlags, point);
174 }
175
Annot_OnMouseEnter(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)176 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseEnter(
177 CPDFSDK_PageView* pPageView,
178 CPDFSDK_Annot::ObservedPtr* pAnnot,
179 uint32_t nFlag) {
180 ASSERT(*pAnnot);
181 GetAnnotHandler(pAnnot->Get())->OnMouseEnter(pPageView, pAnnot, nFlag);
182 }
183
Annot_OnMouseExit(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)184 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseExit(
185 CPDFSDK_PageView* pPageView,
186 CPDFSDK_Annot::ObservedPtr* pAnnot,
187 uint32_t nFlag) {
188 ASSERT(*pAnnot);
189 GetAnnotHandler(pAnnot->Get())->OnMouseExit(pPageView, pAnnot, nFlag);
190 }
191
Annot_OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)192 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChar(CPDFSDK_Annot* pAnnot,
193 uint32_t nChar,
194 uint32_t nFlags) {
195 return GetAnnotHandler(pAnnot)->OnChar(pAnnot, nChar, nFlags);
196 }
197
Annot_OnKeyDown(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)198 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyDown(CPDFSDK_Annot* pAnnot,
199 int nKeyCode,
200 int nFlag) {
201 if (m_pFormFillEnv->IsCTRLKeyDown(nFlag) ||
202 m_pFormFillEnv->IsALTKeyDown(nFlag)) {
203 return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
204 }
205
206 CPDFSDK_PageView* pPage = pAnnot->GetPageView();
207 CPDFSDK_Annot* pFocusAnnot = pPage->GetFocusAnnot();
208 if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab)) {
209 CPDFSDK_Annot::ObservedPtr pNext(
210 GetNextAnnot(pFocusAnnot, !m_pFormFillEnv->IsSHIFTKeyDown(nFlag)));
211 if (pNext && pNext.Get() != pFocusAnnot) {
212 pPage->GetFormFillEnv()->SetFocusAnnot(&pNext);
213 return true;
214 }
215 }
216
217 return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
218 }
219
Annot_OnKeyUp(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)220 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyUp(CPDFSDK_Annot* pAnnot,
221 int nKeyCode,
222 int nFlag) {
223 return false;
224 }
225
Annot_OnSetFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)226 bool CPDFSDK_AnnotHandlerMgr::Annot_OnSetFocus(
227 CPDFSDK_Annot::ObservedPtr* pAnnot,
228 uint32_t nFlag) {
229 ASSERT(*pAnnot);
230 return GetAnnotHandler(pAnnot->Get())->OnSetFocus(pAnnot, nFlag);
231 }
232
Annot_OnKillFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)233 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(
234 CPDFSDK_Annot::ObservedPtr* pAnnot,
235 uint32_t nFlag) {
236 ASSERT(*pAnnot);
237 return GetAnnotHandler(pAnnot->Get())->OnKillFocus(pAnnot, nFlag);
238 }
239
240 #ifdef PDF_ENABLE_XFA
Annot_OnChangeFocus(CPDFSDK_Annot::ObservedPtr * pSetAnnot,CPDFSDK_Annot::ObservedPtr * pKillAnnot)241 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChangeFocus(
242 CPDFSDK_Annot::ObservedPtr* pSetAnnot,
243 CPDFSDK_Annot::ObservedPtr* pKillAnnot) {
244 bool bXFA = (*pSetAnnot && (*pSetAnnot)->GetXFAWidget()) ||
245 (*pKillAnnot && (*pKillAnnot)->GetXFAWidget());
246
247 if (bXFA) {
248 if (IPDFSDK_AnnotHandler* pXFAAnnotHandler =
249 GetAnnotHandler(CPDF_Annot::Subtype::XFAWIDGET))
250 return pXFAAnnotHandler->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
251 }
252
253 return true;
254 }
255 #endif // PDF_ENABLE_XFA
256
Annot_OnGetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)257 CFX_FloatRect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(
258 CPDFSDK_PageView* pPageView,
259 CPDFSDK_Annot* pAnnot) {
260 ASSERT(pAnnot);
261 return GetAnnotHandler(pAnnot)->GetViewBBox(pPageView, pAnnot);
262 }
263
Annot_OnHitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,const CFX_PointF & point)264 bool CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView* pPageView,
265 CPDFSDK_Annot* pAnnot,
266 const CFX_PointF& point) {
267 ASSERT(pAnnot);
268 IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
269 if (pAnnotHandler->CanAnswer(pAnnot))
270 return pAnnotHandler->HitTest(pPageView, pAnnot, point);
271
272 return false;
273 }
274
GetNextAnnot(CPDFSDK_Annot * pSDKAnnot,bool bNext)275 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,
276 bool bNext) {
277 #ifdef PDF_ENABLE_XFA
278 CPDFSDK_PageView* pPageView = pSDKAnnot->GetPageView();
279 CPDFXFA_Page* pPage = pPageView->GetPDFXFAPage();
280 if (!pPage)
281 return nullptr;
282 if (pPage->GetPDFPage()) { // for pdf annots.
283 CBA_AnnotIterator ai(pSDKAnnot->GetPageView(),
284 pSDKAnnot->GetAnnotSubtype());
285 CPDFSDK_Annot* pNext =
286 bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
287 return pNext;
288 }
289 // for xfa annots
290 std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator(
291 pPage->GetXFAPageView()->CreateWidgetIterator(
292 XFA_TRAVERSEWAY_Tranvalse, XFA_WidgetStatus_Visible |
293 XFA_WidgetStatus_Viewable |
294 XFA_WidgetStatus_Focused));
295 if (!pWidgetIterator)
296 return nullptr;
297 if (pWidgetIterator->GetCurrentWidget() != pSDKAnnot->GetXFAWidget())
298 pWidgetIterator->SetCurrentWidget(pSDKAnnot->GetXFAWidget());
299 CXFA_FFWidget* hNextFocus =
300 bNext ? pWidgetIterator->MoveToNext() : pWidgetIterator->MoveToPrevious();
301 if (!hNextFocus && pSDKAnnot)
302 hNextFocus = pWidgetIterator->MoveToFirst();
303
304 return pPageView->GetAnnotByXFAWidget(hNextFocus);
305 #else // PDF_ENABLE_XFA
306 CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), CPDF_Annot::Subtype::WIDGET);
307 return bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
308 #endif // PDF_ENABLE_XFA
309 }
310