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