• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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