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 <utility>
10
11 #include "core/fpdfapi/parser/cpdf_number.h"
12 #include "core/fpdfapi/parser/cpdf_string.h"
13 #include "core/fpdfdoc/cpdf_annot.h"
14 #include "fpdfsdk/cpdfsdk_annot.h"
15 #include "fpdfsdk/cpdfsdk_annotiterator.h"
16 #include "fpdfsdk/cpdfsdk_baannot.h"
17 #include "fpdfsdk/cpdfsdk_baannothandler.h"
18 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
19 #include "fpdfsdk/cpdfsdk_pageview.h"
20 #include "fpdfsdk/cpdfsdk_widget.h"
21 #include "fpdfsdk/cpdfsdk_widgethandler.h"
22 #include "fpdfsdk/pwl/cpwl_wnd.h"
23 #include "public/fpdf_fwlevent.h"
24 #include "third_party/base/ptr_util.h"
25
26 #ifdef PDF_ENABLE_XFA
27 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
28 #include "fpdfsdk/fpdfxfa/cpdfxfa_widget.h"
29 #include "fpdfsdk/fpdfxfa/cpdfxfa_widgethandler.h"
30 #endif // PDF_ENABLE_XFA
31
CPDFSDK_AnnotHandlerMgr(std::unique_ptr<CPDFSDK_BAAnnotHandler> pBAAnnotHandler,std::unique_ptr<CPDFSDK_WidgetHandler> pWidgetHandler,std::unique_ptr<IPDFSDK_AnnotHandler> pXFAWidgetHandler)32 CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(
33 std::unique_ptr<CPDFSDK_BAAnnotHandler> pBAAnnotHandler,
34 std::unique_ptr<CPDFSDK_WidgetHandler> pWidgetHandler,
35 std::unique_ptr<IPDFSDK_AnnotHandler> pXFAWidgetHandler)
36 : m_pBAAnnotHandler(std::move(pBAAnnotHandler)),
37 m_pWidgetHandler(std::move(pWidgetHandler)),
38 m_pXFAWidgetHandler(std::move(pXFAWidgetHandler)) {
39 ASSERT(m_pBAAnnotHandler);
40 ASSERT(m_pWidgetHandler);
41 }
42
43 CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() = default;
44
SetFormFillEnv(CPDFSDK_FormFillEnvironment * pFormFillEnv)45 void CPDFSDK_AnnotHandlerMgr::SetFormFillEnv(
46 CPDFSDK_FormFillEnvironment* pFormFillEnv) {
47 m_pBAAnnotHandler->SetFormFillEnvironment(pFormFillEnv);
48 m_pWidgetHandler->SetFormFillEnvironment(pFormFillEnv);
49 if (m_pXFAWidgetHandler)
50 m_pXFAWidgetHandler->SetFormFillEnvironment(pFormFillEnv);
51 }
52
NewAnnot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPageView)53 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot* pAnnot,
54 CPDFSDK_PageView* pPageView) {
55 ASSERT(pPageView);
56 return GetAnnotHandlerOfType(pAnnot->GetSubtype())
57 ->NewAnnot(pAnnot, pPageView);
58 }
59
60 #ifdef PDF_ENABLE_XFA
NewXFAAnnot(CXFA_FFWidget * pAnnot,CPDFSDK_PageView * pPageView)61 std::unique_ptr<CPDFSDK_Annot> CPDFSDK_AnnotHandlerMgr::NewXFAAnnot(
62 CXFA_FFWidget* pAnnot,
63 CPDFSDK_PageView* pPageView) {
64 ASSERT(pAnnot);
65 ASSERT(pPageView);
66 return static_cast<CPDFXFA_WidgetHandler*>(m_pXFAWidgetHandler.get())
67 ->NewAnnotForXFA(pAnnot, pPageView);
68 }
69 #endif // PDF_ENABLE_XFA
70
ReleaseAnnot(std::unique_ptr<CPDFSDK_Annot> pAnnot)71 void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(
72 std::unique_ptr<CPDFSDK_Annot> pAnnot) {
73 IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot.get());
74 pAnnotHandler->ReleaseAnnot(std::move(pAnnot));
75 }
76
Annot_OnLoad(CPDFSDK_Annot * pAnnot)77 void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) {
78 ASSERT(pAnnot);
79 GetAnnotHandler(pAnnot)->OnLoad(pAnnot);
80 }
81
Annot_GetText(CPDFSDK_Annot * pAnnot)82 WideString CPDFSDK_AnnotHandlerMgr::Annot_GetText(CPDFSDK_Annot* pAnnot) {
83 return GetAnnotHandler(pAnnot)->GetText(pAnnot);
84 }
85
Annot_GetSelectedText(CPDFSDK_Annot * pAnnot)86 WideString CPDFSDK_AnnotHandlerMgr::Annot_GetSelectedText(
87 CPDFSDK_Annot* pAnnot) {
88 return GetAnnotHandler(pAnnot)->GetSelectedText(pAnnot);
89 }
90
Annot_ReplaceSelection(CPDFSDK_Annot * pAnnot,const WideString & text)91 void CPDFSDK_AnnotHandlerMgr::Annot_ReplaceSelection(CPDFSDK_Annot* pAnnot,
92 const WideString& text) {
93 GetAnnotHandler(pAnnot)->ReplaceSelection(pAnnot, text);
94 }
95
Annot_CanUndo(CPDFSDK_Annot * pAnnot)96 bool CPDFSDK_AnnotHandlerMgr::Annot_CanUndo(CPDFSDK_Annot* pAnnot) {
97 return GetAnnotHandler(pAnnot)->CanUndo(pAnnot);
98 }
99
Annot_CanRedo(CPDFSDK_Annot * pAnnot)100 bool CPDFSDK_AnnotHandlerMgr::Annot_CanRedo(CPDFSDK_Annot* pAnnot) {
101 return GetAnnotHandler(pAnnot)->CanRedo(pAnnot);
102 }
103
Annot_Undo(CPDFSDK_Annot * pAnnot)104 bool CPDFSDK_AnnotHandlerMgr::Annot_Undo(CPDFSDK_Annot* pAnnot) {
105 return GetAnnotHandler(pAnnot)->Undo(pAnnot);
106 }
107
Annot_Redo(CPDFSDK_Annot * pAnnot)108 bool CPDFSDK_AnnotHandlerMgr::Annot_Redo(CPDFSDK_Annot* pAnnot) {
109 return GetAnnotHandler(pAnnot)->Redo(pAnnot);
110 }
111
GetAnnotHandler(CPDFSDK_Annot * pAnnot) const112 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
113 CPDFSDK_Annot* pAnnot) const {
114 return GetAnnotHandlerOfType(pAnnot->GetAnnotSubtype());
115 }
116
GetAnnotHandlerOfType(CPDF_Annot::Subtype nAnnotSubtype) const117 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandlerOfType(
118 CPDF_Annot::Subtype nAnnotSubtype) const {
119 if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET)
120 return m_pWidgetHandler.get();
121
122 #ifdef PDF_ENABLE_XFA
123 if (nAnnotSubtype == CPDF_Annot::Subtype::XFAWIDGET)
124 return m_pXFAWidgetHandler.get();
125 #endif // PDF_ENABLE_XFA
126
127 return m_pBAAnnotHandler.get();
128 }
129
Annot_OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device,bool bDrawAnnots)130 void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView,
131 CPDFSDK_Annot* pAnnot,
132 CFX_RenderDevice* pDevice,
133 const CFX_Matrix& mtUser2Device,
134 bool bDrawAnnots) {
135 ASSERT(pAnnot);
136 GetAnnotHandler(pAnnot)->OnDraw(pPageView, pAnnot, pDevice, mtUser2Device,
137 bDrawAnnots);
138 }
139
Annot_OnLButtonDown(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)140 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown(
141 CPDFSDK_PageView* pPageView,
142 ObservedPtr<CPDFSDK_Annot>* pAnnot,
143 uint32_t nFlags,
144 const CFX_PointF& point) {
145 ASSERT(pAnnot->HasObservable());
146 return GetAnnotHandler(pAnnot->Get())
147 ->OnLButtonDown(pPageView, pAnnot, nFlags, point);
148 }
149
Annot_OnLButtonUp(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)150 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp(
151 CPDFSDK_PageView* pPageView,
152 ObservedPtr<CPDFSDK_Annot>* pAnnot,
153 uint32_t nFlags,
154 const CFX_PointF& point) {
155 ASSERT(pAnnot->HasObservable());
156 return GetAnnotHandler(pAnnot->Get())
157 ->OnLButtonUp(pPageView, pAnnot, nFlags, point);
158 }
159
Annot_OnLButtonDblClk(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)160 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk(
161 CPDFSDK_PageView* pPageView,
162 ObservedPtr<CPDFSDK_Annot>* pAnnot,
163 uint32_t nFlags,
164 const CFX_PointF& point) {
165 ASSERT(pAnnot->HasObservable());
166 return GetAnnotHandler(pAnnot->Get())
167 ->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
168 }
169
Annot_OnMouseMove(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)170 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove(
171 CPDFSDK_PageView* pPageView,
172 ObservedPtr<CPDFSDK_Annot>* pAnnot,
173 uint32_t nFlags,
174 const CFX_PointF& point) {
175 ASSERT(pAnnot->HasObservable());
176 return GetAnnotHandler(pAnnot->Get())
177 ->OnMouseMove(pPageView, pAnnot, nFlags, point);
178 }
179
Annot_OnMouseWheel(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)180 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel(
181 CPDFSDK_PageView* pPageView,
182 ObservedPtr<CPDFSDK_Annot>* pAnnot,
183 uint32_t nFlags,
184 short zDelta,
185 const CFX_PointF& point) {
186 ASSERT(pAnnot->HasObservable());
187 return GetAnnotHandler(pAnnot->Get())
188 ->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
189 }
190
Annot_OnRButtonDown(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)191 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown(
192 CPDFSDK_PageView* pPageView,
193 ObservedPtr<CPDFSDK_Annot>* pAnnot,
194 uint32_t nFlags,
195 const CFX_PointF& point) {
196 ASSERT(pAnnot->HasObservable());
197 return GetAnnotHandler(pAnnot->Get())
198 ->OnRButtonDown(pPageView, pAnnot, nFlags, point);
199 }
200
Annot_OnRButtonUp(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)201 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp(
202 CPDFSDK_PageView* pPageView,
203 ObservedPtr<CPDFSDK_Annot>* pAnnot,
204 uint32_t nFlags,
205 const CFX_PointF& point) {
206 ASSERT(pAnnot->HasObservable());
207 return GetAnnotHandler(pAnnot->Get())
208 ->OnRButtonUp(pPageView, pAnnot, nFlags, point);
209 }
210
Annot_OnMouseEnter(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)211 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseEnter(
212 CPDFSDK_PageView* pPageView,
213 ObservedPtr<CPDFSDK_Annot>* pAnnot,
214 uint32_t nFlag) {
215 ASSERT(pAnnot->HasObservable());
216 GetAnnotHandler(pAnnot->Get())->OnMouseEnter(pPageView, pAnnot, nFlag);
217 }
218
Annot_OnMouseExit(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)219 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseExit(
220 CPDFSDK_PageView* pPageView,
221 ObservedPtr<CPDFSDK_Annot>* pAnnot,
222 uint32_t nFlag) {
223 ASSERT(pAnnot->HasObservable());
224 GetAnnotHandler(pAnnot->Get())->OnMouseExit(pPageView, pAnnot, nFlag);
225 }
226
Annot_OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)227 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChar(CPDFSDK_Annot* pAnnot,
228 uint32_t nChar,
229 uint32_t nFlags) {
230 return GetAnnotHandler(pAnnot)->OnChar(pAnnot, nChar, nFlags);
231 }
232
Annot_OnKeyDown(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)233 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyDown(CPDFSDK_Annot* pAnnot,
234 int nKeyCode,
235 int nFlag) {
236 if (CPWL_Wnd::IsCTRLKeyDown(nFlag) || CPWL_Wnd::IsALTKeyDown(nFlag)) {
237 return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
238 }
239 ObservedPtr<CPDFSDK_Annot> pObservedAnnot(pAnnot);
240 CPDFSDK_PageView* pPage = pAnnot->GetPageView();
241 CPDFSDK_Annot* pFocusAnnot = pPage->GetFocusAnnot();
242 if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab)) {
243 ObservedPtr<CPDFSDK_Annot> pNext(
244 GetNextAnnot(pFocusAnnot, !CPWL_Wnd::IsSHIFTKeyDown(nFlag)));
245 if (pNext && pNext.Get() != pFocusAnnot) {
246 pPage->GetFormFillEnv()->SetFocusAnnot(&pNext);
247 return true;
248 }
249 }
250
251 // Check |pAnnot| again because JS may have destroyed it in |GetNextAnnot|
252 if (!pObservedAnnot)
253 return false;
254
255 return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
256 }
257
Annot_OnSetFocus(ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)258 bool CPDFSDK_AnnotHandlerMgr::Annot_OnSetFocus(
259 ObservedPtr<CPDFSDK_Annot>* pAnnot,
260 uint32_t nFlag) {
261 ASSERT(pAnnot->HasObservable());
262 return GetAnnotHandler(pAnnot->Get())->OnSetFocus(pAnnot, nFlag);
263 }
264
Annot_OnKillFocus(ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)265 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(
266 ObservedPtr<CPDFSDK_Annot>* pAnnot,
267 uint32_t nFlag) {
268 ASSERT(pAnnot->HasObservable());
269 return GetAnnotHandler(pAnnot->Get())->OnKillFocus(pAnnot, nFlag);
270 }
271
Annot_SetIndexSelected(ObservedPtr<CPDFSDK_Annot> * pAnnot,int index,bool selected)272 bool CPDFSDK_AnnotHandlerMgr::Annot_SetIndexSelected(
273 ObservedPtr<CPDFSDK_Annot>* pAnnot,
274 int index,
275 bool selected) {
276 return GetAnnotHandler(pAnnot->Get())
277 ->SetIndexSelected(pAnnot, index, selected);
278 }
279
Annot_IsIndexSelected(ObservedPtr<CPDFSDK_Annot> * pAnnot,int index)280 bool CPDFSDK_AnnotHandlerMgr::Annot_IsIndexSelected(
281 ObservedPtr<CPDFSDK_Annot>* pAnnot,
282 int index) {
283 return GetAnnotHandler(pAnnot->Get())->IsIndexSelected(pAnnot, index);
284 }
285
286 #ifdef PDF_ENABLE_XFA
Annot_OnChangeFocus(ObservedPtr<CPDFSDK_Annot> * pSetAnnot,ObservedPtr<CPDFSDK_Annot> * pKillAnnot)287 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChangeFocus(
288 ObservedPtr<CPDFSDK_Annot>* pSetAnnot,
289 ObservedPtr<CPDFSDK_Annot>* pKillAnnot) {
290 CPDFXFA_Widget* pSetXFAWidget = ToXFAWidget(pSetAnnot->Get());
291 CPDFXFA_Widget* pKillXFAWidget = ToXFAWidget(pKillAnnot->Get());
292 bool bXFA = (pSetXFAWidget && pSetXFAWidget->GetXFAFFWidget()) ||
293 (pKillXFAWidget && pKillXFAWidget->GetXFAFFWidget());
294
295 return !bXFA || static_cast<CPDFXFA_WidgetHandler*>(m_pXFAWidgetHandler.get())
296 ->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
297 }
298 #endif // PDF_ENABLE_XFA
299
Annot_OnGetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)300 CFX_FloatRect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(
301 CPDFSDK_PageView* pPageView,
302 CPDFSDK_Annot* pAnnot) {
303 ASSERT(pAnnot);
304 return GetAnnotHandler(pAnnot)->GetViewBBox(pPageView, pAnnot);
305 }
306
Annot_OnHitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,const CFX_PointF & point)307 bool CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView* pPageView,
308 CPDFSDK_Annot* pAnnot,
309 const CFX_PointF& point) {
310 ASSERT(pAnnot);
311 IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
312 if (pAnnotHandler->CanAnswer(pAnnot))
313 return pAnnotHandler->HitTest(pPageView, pAnnot, point);
314
315 return false;
316 }
317
GetNextAnnot(CPDFSDK_Annot * pSDKAnnot,bool bNext)318 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,
319 bool bNext) {
320 #ifdef PDF_ENABLE_XFA
321 IPDF_Page* pPage = pSDKAnnot->GetPageView()->GetXFAPage();
322 if (pPage && !pPage->AsPDFPage()) {
323 // For xfa annots in XFA pages not backed by PDF pages.
324 return static_cast<CPDFXFA_Page*>(pPage)->GetNextXFAAnnot(pSDKAnnot, bNext);
325 }
326 #endif // PDF_ENABLE_XFA
327
328 // For PDF annots.
329 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pSDKAnnot);
330 CPDFSDK_AnnotIterator ai(pWidget->GetPageView(), pWidget->GetAnnotSubtype());
331 return bNext ? ai.GetNextAnnot(pWidget) : ai.GetPrevAnnot(pWidget);
332 }
333