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