• 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_widgethandler.h"
8 
9 #include <memory>
10 #include <vector>
11 
12 #include "core/fpdfapi/page/cpdf_page.h"
13 #include "core/fpdfapi/parser/cpdf_document.h"
14 #include "core/fpdfdoc/cpdf_interform.h"
15 #include "fpdfsdk/cpdfsdk_annot.h"
16 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
17 #include "fpdfsdk/cpdfsdk_interform.h"
18 #include "fpdfsdk/cpdfsdk_pageview.h"
19 #include "fpdfsdk/cpdfsdk_widget.h"
20 #include "fpdfsdk/formfiller/cffl_formfiller.h"
21 
22 #ifdef PDF_ENABLE_XFA
23 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
24 #endif  // PDF_ENABLE_XFA
25 
CPDFSDK_WidgetHandler(CPDFSDK_FormFillEnvironment * pFormFillEnv)26 CPDFSDK_WidgetHandler::CPDFSDK_WidgetHandler(
27     CPDFSDK_FormFillEnvironment* pFormFillEnv)
28     : m_pFormFillEnv(pFormFillEnv),
29       m_pFormFiller(pFormFillEnv->GetInteractiveFormFiller()) {}
30 
~CPDFSDK_WidgetHandler()31 CPDFSDK_WidgetHandler::~CPDFSDK_WidgetHandler() {}
32 
CanAnswer(CPDFSDK_Annot * pAnnot)33 bool CPDFSDK_WidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
34   ASSERT(pAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET);
35   if (pAnnot->IsSignatureWidget())
36     return false;
37 
38   CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
39   if (!pWidget->IsVisible())
40     return false;
41 
42   int nFieldFlags = pWidget->GetFieldFlags();
43   if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
44     return false;
45 
46   if (pWidget->GetFieldType() == FormFieldType::kPushButton)
47     return true;
48 
49   CPDF_Page* pPage = pWidget->GetPDFPage();
50   uint32_t dwPermissions = pPage->m_pDocument->GetUserPermissions();
51   return (dwPermissions & FPDFPERM_FILL_FORM) ||
52          (dwPermissions & FPDFPERM_ANNOT_FORM);
53 }
54 
NewAnnot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPage)55 CPDFSDK_Annot* CPDFSDK_WidgetHandler::NewAnnot(CPDF_Annot* pAnnot,
56                                                CPDFSDK_PageView* pPage) {
57   CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
58   CPDF_FormControl* pCtrl = CPDFSDK_Widget::GetFormControl(
59       pInterForm->GetInterForm(), pAnnot->GetAnnotDict());
60   if (!pCtrl)
61     return nullptr;
62 
63   CPDFSDK_Widget* pWidget = new CPDFSDK_Widget(pAnnot, pPage, pInterForm);
64   pInterForm->AddMap(pCtrl, pWidget);
65   CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
66   if (pPDFInterForm && pPDFInterForm->NeedConstructAP())
67     pWidget->ResetAppearance(nullptr, false);
68 
69   return pWidget;
70 }
71 
72 #ifdef PDF_ENABLE_XFA
NewAnnot(CXFA_FFWidget * hWidget,CPDFSDK_PageView * pPage)73 CPDFSDK_Annot* CPDFSDK_WidgetHandler::NewAnnot(CXFA_FFWidget* hWidget,
74                                                CPDFSDK_PageView* pPage) {
75   return nullptr;
76 }
77 #endif  // PDF_ENABLE_XFA
78 
ReleaseAnnot(CPDFSDK_Annot * pAnnot)79 void CPDFSDK_WidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
80   ASSERT(pAnnot);
81 
82   if (m_pFormFiller)
83     m_pFormFiller->OnDelete(pAnnot);
84 
85   std::unique_ptr<CPDFSDK_Widget> pWidget(static_cast<CPDFSDK_Widget*>(pAnnot));
86   CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
87   CPDF_FormControl* pControl = pWidget->GetFormControl();
88   pInterForm->RemoveMap(pControl);
89 }
90 
OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device,bool bDrawAnnots)91 void CPDFSDK_WidgetHandler::OnDraw(CPDFSDK_PageView* pPageView,
92                                    CPDFSDK_Annot* pAnnot,
93                                    CFX_RenderDevice* pDevice,
94                                    CFX_Matrix* pUser2Device,
95                                    bool bDrawAnnots) {
96   if (pAnnot->IsSignatureWidget()) {
97     static_cast<CPDFSDK_BAAnnot*>(pAnnot)->DrawAppearance(
98         pDevice, *pUser2Device, CPDF_Annot::Normal, nullptr);
99   } else {
100     if (m_pFormFiller)
101       m_pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device);
102   }
103 }
104 
OnMouseEnter(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)105 void CPDFSDK_WidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
106                                          CPDFSDK_Annot::ObservedPtr* pAnnot,
107                                          uint32_t nFlag) {
108   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
109     m_pFormFiller->OnMouseEnter(pPageView, pAnnot, nFlag);
110 }
111 
OnMouseExit(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)112 void CPDFSDK_WidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
113                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
114                                         uint32_t nFlag) {
115   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
116     m_pFormFiller->OnMouseExit(pPageView, pAnnot, nFlag);
117 }
118 
OnLButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)119 bool CPDFSDK_WidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
120                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
121                                           uint32_t nFlags,
122                                           const CFX_PointF& point) {
123   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
124     return m_pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
125 
126   return false;
127 }
128 
OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)129 bool CPDFSDK_WidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
130                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
131                                         uint32_t nFlags,
132                                         const CFX_PointF& point) {
133   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
134     return m_pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
135 
136   return false;
137 }
138 
OnLButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)139 bool CPDFSDK_WidgetHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
140                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
141                                             uint32_t nFlags,
142                                             const CFX_PointF& point) {
143   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
144     return m_pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
145 
146   return false;
147 }
148 
OnMouseMove(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)149 bool CPDFSDK_WidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
150                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
151                                         uint32_t nFlags,
152                                         const CFX_PointF& point) {
153   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
154     return m_pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
155 
156   return false;
157 }
158 
OnMouseWheel(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)159 bool CPDFSDK_WidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
160                                          CPDFSDK_Annot::ObservedPtr* pAnnot,
161                                          uint32_t nFlags,
162                                          short zDelta,
163                                          const CFX_PointF& point) {
164   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
165     return m_pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta,
166                                        point);
167 
168   return false;
169 }
170 
OnRButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)171 bool CPDFSDK_WidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
172                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
173                                           uint32_t nFlags,
174                                           const CFX_PointF& point) {
175   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
176     return m_pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
177 
178   return false;
179 }
180 
OnRButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)181 bool CPDFSDK_WidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
182                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
183                                         uint32_t nFlags,
184                                         const CFX_PointF& point) {
185   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
186     return m_pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
187 
188   return false;
189 }
190 
OnRButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)191 bool CPDFSDK_WidgetHandler::OnRButtonDblClk(CPDFSDK_PageView* pPageView,
192                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
193                                             uint32_t nFlags,
194                                             const CFX_PointF& point) {
195   return false;
196 }
197 
OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)198 bool CPDFSDK_WidgetHandler::OnChar(CPDFSDK_Annot* pAnnot,
199                                    uint32_t nChar,
200                                    uint32_t nFlags) {
201   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
202     return m_pFormFiller->OnChar(pAnnot, nChar, nFlags);
203 
204   return false;
205 }
206 
OnKeyDown(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)207 bool CPDFSDK_WidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
208                                       int nKeyCode,
209                                       int nFlag) {
210   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
211     return m_pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlag);
212 
213   return false;
214 }
215 
OnKeyUp(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)216 bool CPDFSDK_WidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
217                                     int nKeyCode,
218                                     int nFlag) {
219   return false;
220 }
221 
OnLoad(CPDFSDK_Annot * pAnnot)222 void CPDFSDK_WidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) {
223   if (pAnnot->IsSignatureWidget())
224     return;
225 
226   CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
227   if (!pWidget->IsAppearanceValid())
228     pWidget->ResetAppearance(nullptr, false);
229 
230   FormFieldType fieldType = pWidget->GetFieldType();
231   if (fieldType == FormFieldType::kTextField ||
232       fieldType == FormFieldType::kComboBox) {
233     bool bFormatted = false;
234     CPDFSDK_Annot::ObservedPtr pObserved(pWidget);
235     WideString sValue = pWidget->OnFormat(bFormatted);
236     if (!pObserved)
237       return;
238 
239     if (bFormatted && fieldType == FormFieldType::kComboBox)
240       pWidget->ResetAppearance(&sValue, false);
241   }
242 
243 #ifdef PDF_ENABLE_XFA
244   CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
245   CPDFXFA_Context* pContext = pPageView->GetFormFillEnv()->GetXFAContext();
246   if (pContext->GetFormType() == FormType::kXFAForeground) {
247     if (!pWidget->IsAppearanceValid() && !pWidget->GetValue().IsEmpty())
248       pWidget->ResetAppearance(false);
249   }
250 #endif  // PDF_ENABLE_XFA
251 }
252 
OnSetFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)253 bool CPDFSDK_WidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
254                                        uint32_t nFlag) {
255   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
256     return m_pFormFiller->OnSetFocus(pAnnot, nFlag);
257 
258   return true;
259 }
260 
OnKillFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)261 bool CPDFSDK_WidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
262                                         uint32_t nFlag) {
263   if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
264     return m_pFormFiller->OnKillFocus(pAnnot, nFlag);
265 
266   return true;
267 }
268 
269 #ifdef PDF_ENABLE_XFA
OnXFAChangedFocus(CPDFSDK_Annot::ObservedPtr * pOldAnnot,CPDFSDK_Annot::ObservedPtr * pNewAnnot)270 bool CPDFSDK_WidgetHandler::OnXFAChangedFocus(
271     CPDFSDK_Annot::ObservedPtr* pOldAnnot,
272     CPDFSDK_Annot::ObservedPtr* pNewAnnot) {
273   return true;
274 }
275 #endif  // PDF_ENABLE_XFA
276 
GetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)277 CFX_FloatRect CPDFSDK_WidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
278                                                  CPDFSDK_Annot* pAnnot) {
279   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
280     return CFX_FloatRect(m_pFormFiller->GetViewBBox(pPageView, pAnnot));
281   return CFX_FloatRect();
282 }
283 
GetSelectedText(CPDFSDK_Annot * pAnnot)284 WideString CPDFSDK_WidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) {
285   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
286     return m_pFormFiller->GetSelectedText(pAnnot);
287 
288   return WideString();
289 }
290 
ReplaceSelection(CPDFSDK_Annot * pAnnot,const WideString & text)291 void CPDFSDK_WidgetHandler::ReplaceSelection(CPDFSDK_Annot* pAnnot,
292                                              const WideString& text) {
293   if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
294     m_pFormFiller->ReplaceSelection(pAnnot, text);
295 }
296 
HitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,const CFX_PointF & point)297 bool CPDFSDK_WidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
298                                     CPDFSDK_Annot* pAnnot,
299                                     const CFX_PointF& point) {
300   ASSERT(pPageView);
301   ASSERT(pAnnot);
302   return GetViewBBox(pPageView, pAnnot).Contains(point);
303 }
304