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