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