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_xfawidgethandler.h"
8
9 #include "core/fpdfdoc/cpdf_interform.h"
10 #include "fpdfsdk/cpdfsdk_annot.h"
11 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
12 #include "fpdfsdk/cpdfsdk_interform.h"
13 #include "fpdfsdk/cpdfsdk_pageview.h"
14 #include "fpdfsdk/cpdfsdk_xfawidget.h"
15 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
16 #include "xfa/fwl/cfwl_app.h"
17 #include "xfa/fwl/fwl_widgethit.h"
18 #include "xfa/fxfa/cxfa_ffdocview.h"
19 #include "xfa/fxfa/cxfa_ffpageview.h"
20 #include "xfa/fxfa/cxfa_ffwidget.h"
21 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
22 #include "xfa/fxfa/fxfa_basic.h"
23 #include "xfa/fxfa/parser/cxfa_node.h"
24 #include "xfa/fxgraphics/cxfa_graphics.h"
25
CPDFSDK_XFAWidgetHandler(CPDFSDK_FormFillEnvironment * pFormFillEnv)26 CPDFSDK_XFAWidgetHandler::CPDFSDK_XFAWidgetHandler(
27 CPDFSDK_FormFillEnvironment* pFormFillEnv)
28 : m_pFormFillEnv(pFormFillEnv) {}
29
~CPDFSDK_XFAWidgetHandler()30 CPDFSDK_XFAWidgetHandler::~CPDFSDK_XFAWidgetHandler() {}
31
CanAnswer(CPDFSDK_Annot * pAnnot)32 bool CPDFSDK_XFAWidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
33 return !!pAnnot->GetXFAWidget();
34 }
35
NewAnnot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPage)36 CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CPDF_Annot* pAnnot,
37 CPDFSDK_PageView* pPage) {
38 return nullptr;
39 }
40
NewAnnot(CXFA_FFWidget * pAnnot,CPDFSDK_PageView * pPage)41 CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CXFA_FFWidget* pAnnot,
42 CPDFSDK_PageView* pPage) {
43 CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
44 CPDFSDK_XFAWidget* pWidget = new CPDFSDK_XFAWidget(pAnnot, pPage, pInterForm);
45 pInterForm->AddXFAMap(pAnnot, pWidget);
46 return pWidget;
47 }
48
OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device,bool bDrawAnnots)49 void CPDFSDK_XFAWidgetHandler::OnDraw(CPDFSDK_PageView* pPageView,
50 CPDFSDK_Annot* pAnnot,
51 CFX_RenderDevice* pDevice,
52 CFX_Matrix* pUser2Device,
53 bool bDrawAnnots) {
54 ASSERT(pPageView);
55 ASSERT(pAnnot);
56
57 CXFA_Graphics gs(pDevice);
58
59 CFX_Matrix mt = *pUser2Device;
60 bool bIsHighlight = false;
61 if (pPageView->GetFormFillEnv()->GetFocusAnnot() != pAnnot)
62 bIsHighlight = true;
63
64 GetXFAWidgetHandler(pAnnot)->RenderWidget(pAnnot->GetXFAWidget(), &gs, mt,
65 bIsHighlight);
66
67 // to do highlight and shadow
68 }
69
OnLoad(CPDFSDK_Annot * pAnnot)70 void CPDFSDK_XFAWidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) {}
71
ReleaseAnnot(CPDFSDK_Annot * pAnnot)72 void CPDFSDK_XFAWidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
73 CPDFSDK_XFAWidget* pWidget = reinterpret_cast<CPDFSDK_XFAWidget*>(pAnnot);
74 CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
75 pInterForm->RemoveXFAMap(pWidget->GetXFAWidget());
76
77 delete pWidget;
78 }
79
GetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)80 CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
81 CPDFSDK_Annot* pAnnot) {
82 ASSERT(pAnnot);
83
84 CFX_RectF rcBBox;
85 XFA_Element eType =
86 pAnnot->GetXFAWidget()->GetNode()->GetWidgetAcc()->GetUIType();
87 if (eType == XFA_Element::Signature)
88 rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_Visible, true);
89 else
90 rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_None);
91
92 CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
93 rcBBox.top + rcBBox.height);
94 rcWidget.left -= 1.0f;
95 rcWidget.right += 1.0f;
96 rcWidget.bottom -= 1.0f;
97 rcWidget.top += 1.0f;
98
99 return rcWidget;
100 }
101
GetSelectedText(CPDFSDK_Annot * pAnnot)102 WideString CPDFSDK_XFAWidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) {
103 if (!pAnnot)
104 return WideString();
105
106 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
107 return pWidgetHandler->GetSelectedText(pAnnot->GetXFAWidget());
108 }
109
ReplaceSelection(CPDFSDK_Annot * pAnnot,const WideString & text)110 void CPDFSDK_XFAWidgetHandler::ReplaceSelection(CPDFSDK_Annot* pAnnot,
111 const WideString& text) {
112 if (!pAnnot)
113 return;
114
115 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
116 return pWidgetHandler->PasteText(pAnnot->GetXFAWidget(), text);
117 }
118
HitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,const CFX_PointF & point)119 bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
120 CPDFSDK_Annot* pAnnot,
121 const CFX_PointF& point) {
122 if (!pPageView || !pAnnot)
123 return false;
124
125 CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
126 if (!pFormFillEnv)
127 return false;
128
129 CPDFXFA_Context* pContext = pFormFillEnv->GetXFAContext();
130 if (!pContext)
131 return false;
132
133 CXFA_FFDocView* pDocView = pContext->GetXFADocView();
134 if (!pDocView)
135 return false;
136
137 CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
138 if (!pWidgetHandler)
139 return false;
140
141 FWL_WidgetHit dwHitTest =
142 pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point);
143 return dwHitTest != FWL_WidgetHit::Unknown;
144 }
145
OnMouseEnter(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)146 void CPDFSDK_XFAWidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
147 CPDFSDK_Annot::ObservedPtr* pAnnot,
148 uint32_t nFlag) {
149 if (!pPageView || !(*pAnnot))
150 return;
151 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
152 pWidgetHandler->OnMouseEnter((*pAnnot)->GetXFAWidget());
153 }
154
OnMouseExit(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)155 void CPDFSDK_XFAWidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
156 CPDFSDK_Annot::ObservedPtr* pAnnot,
157 uint32_t nFlag) {
158 if (!pPageView || !(*pAnnot))
159 return;
160
161 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
162 pWidgetHandler->OnMouseExit((*pAnnot)->GetXFAWidget());
163 }
164
OnLButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)165 bool CPDFSDK_XFAWidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
166 CPDFSDK_Annot::ObservedPtr* pAnnot,
167 uint32_t nFlags,
168 const CFX_PointF& point) {
169 if (!pPageView || !(*pAnnot))
170 return false;
171
172 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
173 return pWidgetHandler->OnLButtonDown((*pAnnot)->GetXFAWidget(),
174 GetFWLFlags(nFlags), point);
175 }
176
OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)177 bool CPDFSDK_XFAWidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
178 CPDFSDK_Annot::ObservedPtr* pAnnot,
179 uint32_t nFlags,
180 const CFX_PointF& point) {
181 if (!pPageView || !(*pAnnot))
182 return false;
183
184 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
185 return pWidgetHandler->OnLButtonUp((*pAnnot)->GetXFAWidget(),
186 GetFWLFlags(nFlags), point);
187 }
188
OnLButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)189 bool CPDFSDK_XFAWidgetHandler::OnLButtonDblClk(
190 CPDFSDK_PageView* pPageView,
191 CPDFSDK_Annot::ObservedPtr* pAnnot,
192 uint32_t nFlags,
193 const CFX_PointF& point) {
194 if (!pPageView || !(*pAnnot))
195 return false;
196
197 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
198 return pWidgetHandler->OnLButtonDblClk((*pAnnot)->GetXFAWidget(),
199 GetFWLFlags(nFlags), point);
200 }
201
OnMouseMove(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)202 bool CPDFSDK_XFAWidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
203 CPDFSDK_Annot::ObservedPtr* pAnnot,
204 uint32_t nFlags,
205 const CFX_PointF& point) {
206 if (!pPageView || !(*pAnnot))
207 return false;
208
209 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
210 return pWidgetHandler->OnMouseMove((*pAnnot)->GetXFAWidget(),
211 GetFWLFlags(nFlags), point);
212 }
213
OnMouseWheel(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)214 bool CPDFSDK_XFAWidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
215 CPDFSDK_Annot::ObservedPtr* pAnnot,
216 uint32_t nFlags,
217 short zDelta,
218 const CFX_PointF& point) {
219 if (!pPageView || !(*pAnnot))
220 return false;
221
222 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
223 return pWidgetHandler->OnMouseWheel((*pAnnot)->GetXFAWidget(),
224 GetFWLFlags(nFlags), zDelta, point);
225 }
226
OnRButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)227 bool CPDFSDK_XFAWidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
228 CPDFSDK_Annot::ObservedPtr* pAnnot,
229 uint32_t nFlags,
230 const CFX_PointF& point) {
231 if (!pPageView || !(*pAnnot))
232 return false;
233
234 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
235 return pWidgetHandler->OnRButtonDown((*pAnnot)->GetXFAWidget(),
236 GetFWLFlags(nFlags), point);
237 }
238
OnRButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)239 bool CPDFSDK_XFAWidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
240 CPDFSDK_Annot::ObservedPtr* pAnnot,
241 uint32_t nFlags,
242 const CFX_PointF& point) {
243 if (!pPageView || !(*pAnnot))
244 return false;
245
246 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
247 return pWidgetHandler->OnRButtonUp((*pAnnot)->GetXFAWidget(),
248 GetFWLFlags(nFlags), point);
249 }
250
OnRButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)251 bool CPDFSDK_XFAWidgetHandler::OnRButtonDblClk(
252 CPDFSDK_PageView* pPageView,
253 CPDFSDK_Annot::ObservedPtr* pAnnot,
254 uint32_t nFlags,
255 const CFX_PointF& point) {
256 if (!pPageView || !(*pAnnot))
257 return false;
258
259 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
260 return pWidgetHandler->OnRButtonDblClk((*pAnnot)->GetXFAWidget(),
261 GetFWLFlags(nFlags), point);
262 }
263
OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)264 bool CPDFSDK_XFAWidgetHandler::OnChar(CPDFSDK_Annot* pAnnot,
265 uint32_t nChar,
266 uint32_t nFlags) {
267 if (!pAnnot)
268 return false;
269
270 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
271 return pWidgetHandler->OnChar(pAnnot->GetXFAWidget(), nChar,
272 GetFWLFlags(nFlags));
273 }
274
OnKeyDown(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)275 bool CPDFSDK_XFAWidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
276 int nKeyCode,
277 int nFlag) {
278 if (!pAnnot)
279 return false;
280
281 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
282 return pWidgetHandler->OnKeyDown(pAnnot->GetXFAWidget(), nKeyCode,
283 GetFWLFlags(nFlag));
284 }
285
OnKeyUp(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)286 bool CPDFSDK_XFAWidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
287 int nKeyCode,
288 int nFlag) {
289 if (!pAnnot)
290 return false;
291
292 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
293 return pWidgetHandler->OnKeyUp(pAnnot->GetXFAWidget(), nKeyCode,
294 GetFWLFlags(nFlag));
295 }
296
OnSetFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)297 bool CPDFSDK_XFAWidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
298 uint32_t nFlag) {
299 return true;
300 }
301
OnKillFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)302 bool CPDFSDK_XFAWidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
303 uint32_t nFlag) {
304 return true;
305 }
306
OnXFAChangedFocus(CPDFSDK_Annot::ObservedPtr * pOldAnnot,CPDFSDK_Annot::ObservedPtr * pNewAnnot)307 bool CPDFSDK_XFAWidgetHandler::OnXFAChangedFocus(
308 CPDFSDK_Annot::ObservedPtr* pOldAnnot,
309 CPDFSDK_Annot::ObservedPtr* pNewAnnot) {
310 CXFA_FFWidgetHandler* pWidgetHandler = nullptr;
311 if (*pOldAnnot)
312 pWidgetHandler = GetXFAWidgetHandler(pOldAnnot->Get());
313 else if (*pNewAnnot)
314 pWidgetHandler = GetXFAWidgetHandler(pNewAnnot->Get());
315
316 if (!pWidgetHandler)
317 return true;
318
319 CXFA_FFWidget* hWidget = *pNewAnnot ? (*pNewAnnot)->GetXFAWidget() : nullptr;
320 if (!hWidget)
321 return true;
322
323 CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
324 if (!pXFAPageView)
325 return true;
326
327 bool bRet = pXFAPageView->GetDocView()->SetFocus(hWidget);
328 if (pXFAPageView->GetDocView()->GetFocusWidget() == hWidget)
329 bRet = true;
330
331 return bRet;
332 }
333
GetXFAWidgetHandler(CPDFSDK_Annot * pAnnot)334 CXFA_FFWidgetHandler* CPDFSDK_XFAWidgetHandler::GetXFAWidgetHandler(
335 CPDFSDK_Annot* pAnnot) {
336 if (!pAnnot)
337 return nullptr;
338
339 CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
340 if (!pPageView)
341 return nullptr;
342
343 CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
344 if (!pFormFillEnv)
345 return nullptr;
346
347 CPDFXFA_Context* pDoc = pFormFillEnv->GetXFAContext();
348 if (!pDoc)
349 return nullptr;
350
351 CXFA_FFDocView* pDocView = pDoc->GetXFADocView();
352 if (!pDocView)
353 return nullptr;
354
355 return pDocView->GetWidgetHandler();
356 }
357
GetFWLFlags(uint32_t dwFlag)358 uint32_t CPDFSDK_XFAWidgetHandler::GetFWLFlags(uint32_t dwFlag) {
359 uint32_t dwFWLFlag = 0;
360
361 if (dwFlag & FWL_EVENTFLAG_ControlKey)
362 dwFWLFlag |= FWL_KEYFLAG_Ctrl;
363 if (dwFlag & FWL_EVENTFLAG_LeftButtonDown)
364 dwFWLFlag |= FWL_KEYFLAG_LButton;
365 if (dwFlag & FWL_EVENTFLAG_MiddleButtonDown)
366 dwFWLFlag |= FWL_KEYFLAG_MButton;
367 if (dwFlag & FWL_EVENTFLAG_RightButtonDown)
368 dwFWLFlag |= FWL_KEYFLAG_RButton;
369 if (dwFlag & FWL_EVENTFLAG_ShiftKey)
370 dwFWLFlag |= FWL_KEYFLAG_Shift;
371 if (dwFlag & FWL_EVENTFLAG_AltKey)
372 dwFWLFlag |= FWL_KEYFLAG_Alt;
373
374 return dwFWLFlag;
375 }
376