1 // Copyright 2014 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/include/formfiller/FFL_IFormFiller.h"
8
9 #include "fpdfsdk/include/formfiller/FFL_CheckBox.h"
10 #include "fpdfsdk/include/formfiller/FFL_ComboBox.h"
11 #include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
12 #include "fpdfsdk/include/formfiller/FFL_ListBox.h"
13 #include "fpdfsdk/include/formfiller/FFL_PushButton.h"
14 #include "fpdfsdk/include/formfiller/FFL_RadioButton.h"
15 #include "fpdfsdk/include/formfiller/FFL_TextField.h"
16 #include "fpdfsdk/include/fsdk_mgr.h"
17 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
18
19 #define FFL_MAXLISTBOXHEIGHT 140.0f
20
CFFL_IFormFiller(CPDFDoc_Environment * pApp)21 CFFL_IFormFiller::CFFL_IFormFiller(CPDFDoc_Environment* pApp)
22 : m_pApp(pApp), m_bNotifying(FALSE) {}
23
~CFFL_IFormFiller()24 CFFL_IFormFiller::~CFFL_IFormFiller() {
25 for (auto& it : m_Maps)
26 delete it.second;
27 m_Maps.clear();
28 }
29
Annot_HitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CPDF_Point point)30 FX_BOOL CFFL_IFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView,
31 CPDFSDK_Annot* pAnnot,
32 CPDF_Point point) {
33 CPDF_Rect rc = pAnnot->GetRect();
34 if (rc.Contains(point.x, point.y))
35 return TRUE;
36 return FALSE;
37 }
38
GetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)39 FX_RECT CFFL_IFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
40 CPDFSDK_Annot* pAnnot) {
41 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
42 return pFormFiller->GetViewBBox(pPageView, pAnnot);
43
44 ASSERT(pPageView);
45
46 CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
47 CPDF_Rect rcAnnot;
48 pPDFAnnot->GetRect(rcAnnot);
49
50 CPDF_Rect rcWin = CPWL_Utils::InflateRect(rcAnnot, 1);
51 return rcWin.GetOutterRect();
52 }
53
OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device,FX_DWORD dwFlags)54 void CFFL_IFormFiller::OnDraw(CPDFSDK_PageView* pPageView,
55 CPDFSDK_Annot* pAnnot,
56 CFX_RenderDevice* pDevice,
57 CFX_Matrix* pUser2Device,
58 FX_DWORD dwFlags) {
59 ASSERT(pPageView);
60 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
61
62 if (IsVisible(pWidget)) {
63 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
64 if (pFormFiller->IsValid()) {
65 pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
66 pAnnot->GetPDFPage();
67
68 CPDFSDK_Document* pDocument = m_pApp->GetSDKDocument();
69 if (pDocument->GetFocusAnnot() == pAnnot) {
70 CPDF_Rect rcFocus = pFormFiller->GetFocusBox(pPageView);
71 if (!rcFocus.IsEmpty()) {
72 CFX_PathData path;
73 path.SetPointCount(5);
74 path.SetPoint(0, rcFocus.left, rcFocus.top, FXPT_MOVETO);
75 path.SetPoint(1, rcFocus.left, rcFocus.bottom, FXPT_LINETO);
76 path.SetPoint(2, rcFocus.right, rcFocus.bottom, FXPT_LINETO);
77 path.SetPoint(3, rcFocus.right, rcFocus.top, FXPT_LINETO);
78 path.SetPoint(4, rcFocus.left, rcFocus.top, FXPT_LINETO);
79
80 CFX_GraphStateData gsd;
81 gsd.SetDashCount(1);
82 gsd.m_DashArray[0] = 1.0f;
83 gsd.m_DashPhase = 0;
84 gsd.m_LineWidth = 1.0f;
85 pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
86 ArgbEncode(255, 0, 0, 0), FXFILL_ALTERNATE);
87 }
88 }
89 return;
90 }
91 }
92
93 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
94 pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, pUser2Device,
95 dwFlags);
96 else
97 pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
98
99 if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget))
100 pWidget->DrawShadow(pDevice, pPageView);
101 }
102 }
103
OnCreate(CPDFSDK_Annot * pAnnot)104 void CFFL_IFormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {
105 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
106 pFormFiller->OnCreate(pAnnot);
107 }
108 }
109
OnLoad(CPDFSDK_Annot * pAnnot)110 void CFFL_IFormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {
111 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
112 pFormFiller->OnLoad(pAnnot);
113 }
114 }
115
OnDelete(CPDFSDK_Annot * pAnnot)116 void CFFL_IFormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {
117 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
118 pFormFiller->OnDelete(pAnnot);
119 }
120
121 UnRegisterFormFiller(pAnnot);
122 }
123
OnMouseEnter(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlag)124 void CFFL_IFormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
125 CPDFSDK_Annot* pAnnot,
126 FX_UINT nFlag) {
127 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
128
129 if (!m_bNotifying) {
130 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
131 if (pWidget->GetAAction(CPDF_AAction::CursorEnter)) {
132 m_bNotifying = TRUE;
133
134 int nValueAge = pWidget->GetValueAge();
135
136 pWidget->ClearAppModified();
137
138 ASSERT(pPageView);
139
140 PDFSDK_FieldAction fa;
141 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
142 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
143 pWidget->OnAAction(CPDF_AAction::CursorEnter, fa, pPageView);
144 m_bNotifying = FALSE;
145
146 if (pWidget->IsAppModified()) {
147 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
148 pFormFiller->ResetPDFWindow(pPageView,
149 pWidget->GetValueAge() == nValueAge);
150 }
151 }
152 }
153 }
154
155 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE)) {
156 pFormFiller->OnMouseEnter(pPageView, pAnnot);
157 }
158 }
159
OnMouseExit(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlag)160 void CFFL_IFormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
161 CPDFSDK_Annot* pAnnot,
162 FX_UINT nFlag) {
163 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
164
165 if (!m_bNotifying) {
166 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
167 if (pWidget->GetAAction(CPDF_AAction::CursorExit)) {
168 m_bNotifying = TRUE;
169 pWidget->GetAppearanceAge();
170 int nValueAge = pWidget->GetValueAge();
171 pWidget->ClearAppModified();
172
173 ASSERT(pPageView);
174
175 PDFSDK_FieldAction fa;
176 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
177 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
178
179 pWidget->OnAAction(CPDF_AAction::CursorExit, fa, pPageView);
180 m_bNotifying = FALSE;
181
182 if (pWidget->IsAppModified()) {
183 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
184 pFormFiller->ResetPDFWindow(pPageView,
185 nValueAge == pWidget->GetValueAge());
186 }
187 }
188 }
189 }
190
191 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
192 pFormFiller->OnMouseExit(pPageView, pAnnot);
193 }
194 }
195
OnLButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlags,const CPDF_Point & point)196 FX_BOOL CFFL_IFormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
197 CPDFSDK_Annot* pAnnot,
198 FX_UINT nFlags,
199 const CPDF_Point& point) {
200 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
201
202 if (!m_bNotifying) {
203 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
204 if (Annot_HitTest(pPageView, pAnnot, point) &&
205 pWidget->GetAAction(CPDF_AAction::ButtonDown)) {
206 m_bNotifying = TRUE;
207 pWidget->GetAppearanceAge();
208 int nValueAge = pWidget->GetValueAge();
209 pWidget->ClearAppModified();
210
211 ASSERT(pPageView);
212
213 PDFSDK_FieldAction fa;
214 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlags);
215 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlags);
216 pWidget->OnAAction(CPDF_AAction::ButtonDown, fa, pPageView);
217 m_bNotifying = FALSE;
218
219 if (!IsValidAnnot(pPageView, pAnnot))
220 return TRUE;
221
222 if (pWidget->IsAppModified()) {
223 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
224 pFormFiller->ResetPDFWindow(pPageView,
225 nValueAge == pWidget->GetValueAge());
226 }
227 }
228 }
229 }
230
231 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
232 return pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
233 }
234
235 return FALSE;
236 }
237
OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlags,const CPDF_Point & point)238 FX_BOOL CFFL_IFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
239 CPDFSDK_Annot* pAnnot,
240 FX_UINT nFlags,
241 const CPDF_Point& point) {
242 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
243 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
244 CPDFSDK_Document* pDocument = m_pApp->GetSDKDocument();
245
246 switch (pWidget->GetFieldType()) {
247 case FIELDTYPE_PUSHBUTTON:
248 case FIELDTYPE_CHECKBOX:
249 case FIELDTYPE_RADIOBUTTON:
250 if (GetViewBBox(pPageView, pAnnot).Contains((int)point.x, (int)point.y))
251 pDocument->SetFocusAnnot(pAnnot);
252 break;
253 default:
254 pDocument->SetFocusAnnot(pAnnot);
255 break;
256 }
257
258 FX_BOOL bRet = FALSE;
259
260 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
261 bRet = pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
262 }
263
264 if (pDocument->GetFocusAnnot() == pAnnot) {
265 FX_BOOL bExit = FALSE;
266 FX_BOOL bReset = FALSE;
267 OnButtonUp(pWidget, pPageView, bReset, bExit, nFlags);
268 if (bExit)
269 return TRUE;
270 #ifdef PDF_ENABLE_XFA
271 OnClick(pWidget, pPageView, bReset, bExit, nFlags);
272 if (bExit)
273 return TRUE;
274 #endif // PDF_ENABLE_XFA
275 }
276 return bRet;
277 }
278
OnButtonUp(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bReset,FX_BOOL & bExit,FX_UINT nFlag)279 void CFFL_IFormFiller::OnButtonUp(CPDFSDK_Widget* pWidget,
280 CPDFSDK_PageView* pPageView,
281 FX_BOOL& bReset,
282 FX_BOOL& bExit,
283 FX_UINT nFlag) {
284 ASSERT(pWidget);
285
286 if (!m_bNotifying) {
287 if (pWidget->GetAAction(CPDF_AAction::ButtonUp)) {
288 m_bNotifying = TRUE;
289 int nAge = pWidget->GetAppearanceAge();
290 int nValueAge = pWidget->GetValueAge();
291
292 ASSERT(pPageView);
293
294 PDFSDK_FieldAction fa;
295 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
296 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
297
298 pWidget->OnAAction(CPDF_AAction::ButtonUp, fa, pPageView);
299 m_bNotifying = FALSE;
300
301 if (!IsValidAnnot(pPageView, pWidget)) {
302 bExit = TRUE;
303 return;
304 }
305
306 if (nAge != pWidget->GetAppearanceAge()) {
307 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
308 pFormFiller->ResetPDFWindow(pPageView,
309 nValueAge == pWidget->GetValueAge());
310 }
311
312 bReset = TRUE;
313 }
314 }
315 }
316 }
317
OnLButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlags,const CPDF_Point & point)318 FX_BOOL CFFL_IFormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
319 CPDFSDK_Annot* pAnnot,
320 FX_UINT nFlags,
321 const CPDF_Point& point) {
322 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
323
324 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
325 return pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
326 }
327
328 return FALSE;
329 }
330
OnMouseMove(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlags,const CPDF_Point & point)331 FX_BOOL CFFL_IFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
332 CPDFSDK_Annot* pAnnot,
333 FX_UINT nFlags,
334 const CPDF_Point& point) {
335 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
336
337 // change cursor
338 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE)) {
339 return pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
340 }
341
342 return FALSE;
343 }
344
OnMouseWheel(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlags,short zDelta,const CPDF_Point & point)345 FX_BOOL CFFL_IFormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
346 CPDFSDK_Annot* pAnnot,
347 FX_UINT nFlags,
348 short zDelta,
349 const CPDF_Point& point) {
350 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
351
352 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
353 return pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
354 }
355
356 return FALSE;
357 }
358
OnRButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlags,const CPDF_Point & point)359 FX_BOOL CFFL_IFormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
360 CPDFSDK_Annot* pAnnot,
361 FX_UINT nFlags,
362 const CPDF_Point& point) {
363 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
364
365 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
366 return pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
367 }
368
369 return FALSE;
370 }
371
OnRButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,FX_UINT nFlags,const CPDF_Point & point)372 FX_BOOL CFFL_IFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
373 CPDFSDK_Annot* pAnnot,
374 FX_UINT nFlags,
375 const CPDF_Point& point) {
376 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
377
378 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
379 return pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
380 }
381
382 return FALSE;
383 }
384
OnKeyDown(CPDFSDK_Annot * pAnnot,FX_UINT nKeyCode,FX_UINT nFlags)385 FX_BOOL CFFL_IFormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
386 FX_UINT nKeyCode,
387 FX_UINT nFlags) {
388 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
389
390 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
391 return pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlags);
392 }
393
394 return FALSE;
395 }
396
OnChar(CPDFSDK_Annot * pAnnot,FX_UINT nChar,FX_UINT nFlags)397 FX_BOOL CFFL_IFormFiller::OnChar(CPDFSDK_Annot* pAnnot,
398 FX_UINT nChar,
399 FX_UINT nFlags) {
400 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
401 if (nChar == FWL_VKEY_Tab)
402 return TRUE;
403
404 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
405 return pFormFiller->OnChar(pAnnot, nChar, nFlags);
406
407 return FALSE;
408 }
409
OnSetFocus(CPDFSDK_Annot * pAnnot,FX_UINT nFlag)410 FX_BOOL CFFL_IFormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
411 if (!pAnnot)
412 return FALSE;
413
414 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
415
416 if (!m_bNotifying) {
417 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
418 if (pWidget->GetAAction(CPDF_AAction::GetFocus)) {
419 m_bNotifying = TRUE;
420 pWidget->GetAppearanceAge();
421
422 int nValueAge = pWidget->GetValueAge();
423 pWidget->ClearAppModified();
424
425 CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
426 ASSERT(pPageView);
427
428 PDFSDK_FieldAction fa;
429 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
430 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
431
432 CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, TRUE);
433 if (!pFormFiller)
434 return FALSE;
435 pFormFiller->GetActionData(pPageView, CPDF_AAction::GetFocus, fa);
436 pWidget->OnAAction(CPDF_AAction::GetFocus, fa, pPageView);
437 m_bNotifying = FALSE;
438
439 if (pWidget->IsAppModified()) {
440 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
441 pFormFiller->ResetPDFWindow(pPageView,
442 nValueAge == pWidget->GetValueAge());
443 }
444 }
445 }
446 }
447
448 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
449 pFormFiller->SetFocusForAnnot(pAnnot, nFlag);
450
451 return TRUE;
452 }
453
OnKillFocus(CPDFSDK_Annot * pAnnot,FX_UINT nFlag)454 FX_BOOL CFFL_IFormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
455 if (!pAnnot)
456 return FALSE;
457 ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
458
459 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
460 pFormFiller->KillFocusForAnnot(pAnnot, nFlag);
461
462 if (!m_bNotifying) {
463 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
464 if (pWidget->GetAAction(CPDF_AAction::LoseFocus)) {
465 m_bNotifying = TRUE;
466 pWidget->ClearAppModified();
467
468 CPDFSDK_PageView* pPageView = pWidget->GetPageView();
469 ASSERT(pPageView);
470
471 PDFSDK_FieldAction fa;
472 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
473 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
474
475 pFormFiller->GetActionData(pPageView, CPDF_AAction::LoseFocus, fa);
476
477 pWidget->OnAAction(CPDF_AAction::LoseFocus, fa, pPageView);
478 m_bNotifying = FALSE;
479 }
480 }
481 }
482
483 return TRUE;
484 }
485
IsVisible(CPDFSDK_Widget * pWidget)486 FX_BOOL CFFL_IFormFiller::IsVisible(CPDFSDK_Widget* pWidget) {
487 return pWidget->IsVisible();
488 }
489
IsReadOnly(CPDFSDK_Widget * pWidget)490 FX_BOOL CFFL_IFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget) {
491 int nFieldFlags = pWidget->GetFieldFlags();
492 return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
493 }
494
IsFillingAllowed(CPDFSDK_Widget * pWidget)495 FX_BOOL CFFL_IFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget) {
496 if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
497 return TRUE;
498
499 CPDF_Page* pPage = pWidget->GetPDFPage();
500 CPDF_Document* pDocument = pPage->m_pDocument;
501 FX_DWORD dwPermissions = pDocument->GetUserPermissions();
502 return (dwPermissions & FPDFPERM_FILL_FORM) ||
503 (dwPermissions & FPDFPERM_ANNOT_FORM) ||
504 (dwPermissions & FPDFPERM_MODIFY);
505 }
506
GetFormFiller(CPDFSDK_Annot * pAnnot,FX_BOOL bRegister)507 CFFL_FormFiller* CFFL_IFormFiller::GetFormFiller(CPDFSDK_Annot* pAnnot,
508 FX_BOOL bRegister) {
509 auto it = m_Maps.find(pAnnot);
510 if (it != m_Maps.end())
511 return it->second;
512
513 if (!bRegister)
514 return nullptr;
515
516 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
517 int nFieldType = pWidget->GetFieldType();
518 CFFL_FormFiller* pFormFiller;
519 switch (nFieldType) {
520 case FIELDTYPE_PUSHBUTTON:
521 pFormFiller = new CFFL_PushButton(m_pApp, pWidget);
522 break;
523 case FIELDTYPE_CHECKBOX:
524 pFormFiller = new CFFL_CheckBox(m_pApp, pWidget);
525 break;
526 case FIELDTYPE_RADIOBUTTON:
527 pFormFiller = new CFFL_RadioButton(m_pApp, pWidget);
528 break;
529 case FIELDTYPE_TEXTFIELD:
530 pFormFiller = new CFFL_TextField(m_pApp, pWidget);
531 break;
532 case FIELDTYPE_LISTBOX:
533 pFormFiller = new CFFL_ListBox(m_pApp, pWidget);
534 break;
535 case FIELDTYPE_COMBOBOX:
536 pFormFiller = new CFFL_ComboBox(m_pApp, pWidget);
537 break;
538 case FIELDTYPE_UNKNOWN:
539 default:
540 pFormFiller = nullptr;
541 break;
542 }
543
544 if (!pFormFiller)
545 return nullptr;
546
547 m_Maps[pAnnot] = pFormFiller;
548 return pFormFiller;
549 }
550
RemoveFormFiller(CPDFSDK_Annot * pAnnot)551 void CFFL_IFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot) {
552 if (pAnnot) {
553 UnRegisterFormFiller(pAnnot);
554 }
555 }
556
UnRegisterFormFiller(CPDFSDK_Annot * pAnnot)557 void CFFL_IFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot) {
558 auto it = m_Maps.find(pAnnot);
559 if (it == m_Maps.end())
560 return;
561
562 delete it->second;
563 m_Maps.erase(it);
564 }
565
QueryWherePopup(void * pPrivateData,FX_FLOAT fPopupMin,FX_FLOAT fPopupMax,int32_t & nRet,FX_FLOAT & fPopupRet)566 void CFFL_IFormFiller::QueryWherePopup(void* pPrivateData,
567 FX_FLOAT fPopupMin,
568 FX_FLOAT fPopupMax,
569 int32_t& nRet,
570 FX_FLOAT& fPopupRet) {
571 CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
572
573 CPDF_Rect rcPageView(0, 0, 0, 0);
574 rcPageView.right = pData->pWidget->GetPDFPage()->GetPageWidth();
575 rcPageView.bottom = pData->pWidget->GetPDFPage()->GetPageHeight();
576 rcPageView.Normalize();
577
578 CPDF_Rect rcAnnot = pData->pWidget->GetRect();
579
580 FX_FLOAT fTop = 0.0f;
581 FX_FLOAT fBottom = 0.0f;
582
583 CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pData->pWidget;
584 switch (pWidget->GetRotate() / 90) {
585 default:
586 case 0:
587 fTop = rcPageView.top - rcAnnot.top;
588 fBottom = rcAnnot.bottom - rcPageView.bottom;
589 break;
590 case 1:
591 fTop = rcAnnot.left - rcPageView.left;
592 fBottom = rcPageView.right - rcAnnot.right;
593 break;
594 case 2:
595 fTop = rcAnnot.bottom - rcPageView.bottom;
596 fBottom = rcPageView.top - rcAnnot.top;
597 break;
598 case 3:
599 fTop = rcPageView.right - rcAnnot.right;
600 fBottom = rcAnnot.left - rcPageView.left;
601 break;
602 }
603
604 FX_FLOAT fFactHeight = 0;
605 FX_BOOL bBottom = TRUE;
606 FX_FLOAT fMaxListBoxHeight = 0;
607 if (fPopupMax > FFL_MAXLISTBOXHEIGHT) {
608 if (fPopupMin > FFL_MAXLISTBOXHEIGHT) {
609 fMaxListBoxHeight = fPopupMin;
610 } else {
611 fMaxListBoxHeight = FFL_MAXLISTBOXHEIGHT;
612 }
613 } else {
614 fMaxListBoxHeight = fPopupMax;
615 }
616
617 if (fBottom > fMaxListBoxHeight) {
618 fFactHeight = fMaxListBoxHeight;
619 bBottom = TRUE;
620 } else {
621 if (fTop > fMaxListBoxHeight) {
622 fFactHeight = fMaxListBoxHeight;
623 bBottom = FALSE;
624 } else {
625 if (fTop > fBottom) {
626 fFactHeight = fTop;
627 bBottom = FALSE;
628 } else {
629 fFactHeight = fBottom;
630 bBottom = TRUE;
631 }
632 }
633 }
634
635 nRet = bBottom ? 0 : 1;
636 fPopupRet = fFactHeight;
637 }
638
OnKeyStrokeCommit(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bRC,FX_BOOL & bExit,FX_DWORD nFlag)639 void CFFL_IFormFiller::OnKeyStrokeCommit(CPDFSDK_Widget* pWidget,
640 CPDFSDK_PageView* pPageView,
641 FX_BOOL& bRC,
642 FX_BOOL& bExit,
643 FX_DWORD nFlag) {
644 if (!m_bNotifying) {
645 if (pWidget->GetAAction(CPDF_AAction::KeyStroke)) {
646 m_bNotifying = TRUE;
647 pWidget->ClearAppModified();
648
649 ASSERT(pPageView);
650
651 PDFSDK_FieldAction fa;
652 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
653 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
654 fa.bWillCommit = TRUE;
655 fa.bKeyDown = TRUE;
656 fa.bRC = TRUE;
657
658 CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
659 pFormFiller->GetActionData(pPageView, CPDF_AAction::KeyStroke, fa);
660 pFormFiller->SaveState(pPageView);
661
662 PDFSDK_FieldAction faOld = fa;
663 pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pPageView);
664
665 bRC = fa.bRC;
666 m_bNotifying = FALSE;
667 }
668 }
669 }
670
OnValidate(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bRC,FX_BOOL & bExit,FX_DWORD nFlag)671 void CFFL_IFormFiller::OnValidate(CPDFSDK_Widget* pWidget,
672 CPDFSDK_PageView* pPageView,
673 FX_BOOL& bRC,
674 FX_BOOL& bExit,
675 FX_DWORD nFlag) {
676 if (!m_bNotifying) {
677 if (pWidget->GetAAction(CPDF_AAction::Validate)) {
678 m_bNotifying = TRUE;
679 pWidget->ClearAppModified();
680
681 ASSERT(pPageView);
682
683 PDFSDK_FieldAction fa;
684 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
685 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
686 fa.bKeyDown = TRUE;
687 fa.bRC = TRUE;
688
689 CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
690 pFormFiller->GetActionData(pPageView, CPDF_AAction::Validate, fa);
691 pFormFiller->SaveState(pPageView);
692
693 PDFSDK_FieldAction faOld = fa;
694 pWidget->OnAAction(CPDF_AAction::Validate, fa, pPageView);
695
696 bRC = fa.bRC;
697 m_bNotifying = FALSE;
698 }
699 }
700 }
701
OnCalculate(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bExit,FX_DWORD nFlag)702 void CFFL_IFormFiller::OnCalculate(CPDFSDK_Widget* pWidget,
703 CPDFSDK_PageView* pPageView,
704 FX_BOOL& bExit,
705 FX_DWORD nFlag) {
706 if (!m_bNotifying) {
707 ASSERT(pWidget);
708 CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
709 CPDFSDK_InterForm* pInterForm =
710 (CPDFSDK_InterForm*)pDocument->GetInterForm();
711 pInterForm->OnCalculate(pWidget->GetFormField());
712
713 m_bNotifying = FALSE;
714 }
715 }
716
OnFormat(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bExit,FX_DWORD nFlag)717 void CFFL_IFormFiller::OnFormat(CPDFSDK_Widget* pWidget,
718 CPDFSDK_PageView* pPageView,
719 FX_BOOL& bExit,
720 FX_DWORD nFlag) {
721 if (!m_bNotifying) {
722 ASSERT(pWidget);
723 CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
724 CPDFSDK_InterForm* pInterForm =
725 (CPDFSDK_InterForm*)pDocument->GetInterForm();
726
727 FX_BOOL bFormated = FALSE;
728 CFX_WideString sValue =
729 pInterForm->OnFormat(pWidget->GetFormField(), bFormated);
730
731 if (bExit)
732 return;
733
734 if (bFormated) {
735 pInterForm->ResetFieldAppearance(pWidget->GetFormField(), sValue.c_str(),
736 TRUE);
737 pInterForm->UpdateField(pWidget->GetFormField());
738 }
739
740 m_bNotifying = FALSE;
741 }
742 }
743
744 #ifdef PDF_ENABLE_XFA
OnClick(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bReset,FX_BOOL & bExit,FX_UINT nFlag)745 void CFFL_IFormFiller::OnClick(CPDFSDK_Widget* pWidget,
746 CPDFSDK_PageView* pPageView,
747 FX_BOOL& bReset,
748 FX_BOOL& bExit,
749 FX_UINT nFlag) {
750 ASSERT(pWidget != NULL);
751
752 if (!m_bNotifying) {
753 if (pWidget->HasXFAAAction(PDFSDK_XFA_Click)) {
754 m_bNotifying = TRUE;
755 int nAge = pWidget->GetAppearanceAge();
756 int nValueAge = pWidget->GetValueAge();
757
758 PDFSDK_FieldAction fa;
759 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
760 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
761
762 pWidget->OnXFAAAction(PDFSDK_XFA_Click, fa, pPageView);
763 m_bNotifying = FALSE;
764
765 if (!IsValidAnnot(pPageView, pWidget)) {
766 bExit = TRUE;
767 return;
768 }
769
770 if (nAge != pWidget->GetAppearanceAge()) {
771 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
772 pFormFiller->ResetPDFWindow(pPageView,
773 nValueAge == pWidget->GetValueAge());
774 }
775
776 bReset = TRUE;
777 }
778 }
779 }
780 }
781
OnFull(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bReset,FX_BOOL & bExit,FX_UINT nFlag)782 void CFFL_IFormFiller::OnFull(CPDFSDK_Widget* pWidget,
783 CPDFSDK_PageView* pPageView,
784 FX_BOOL& bReset,
785 FX_BOOL& bExit,
786 FX_UINT nFlag) {
787 ASSERT(pWidget != NULL);
788
789 if (!m_bNotifying) {
790 if (pWidget->HasXFAAAction(PDFSDK_XFA_Full)) {
791 m_bNotifying = TRUE;
792 int nAge = pWidget->GetAppearanceAge();
793 int nValueAge = pWidget->GetValueAge();
794
795 PDFSDK_FieldAction fa;
796 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
797 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
798
799 pWidget->OnXFAAAction(PDFSDK_XFA_Full, fa, pPageView);
800 m_bNotifying = FALSE;
801
802 if (!IsValidAnnot(pPageView, pWidget)) {
803 bExit = TRUE;
804 return;
805 }
806
807 if (nAge != pWidget->GetAppearanceAge()) {
808 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
809 pFormFiller->ResetPDFWindow(pPageView,
810 nValueAge == pWidget->GetValueAge());
811 }
812
813 bReset = TRUE;
814 }
815 }
816 }
817 }
818
OnPopupPreOpen(void * pPrivateData,FX_BOOL & bExit,FX_DWORD nFlag)819 void CFFL_IFormFiller::OnPopupPreOpen(void* pPrivateData,
820 FX_BOOL& bExit,
821 FX_DWORD nFlag) {
822 ASSERT(pPrivateData != NULL);
823 CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
824 ASSERT(pData->pWidget != NULL);
825
826 FX_BOOL bTempReset = FALSE;
827 FX_BOOL bTempExit = FALSE;
828 this->OnPreOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit,
829 nFlag);
830
831 if (bTempReset || bTempExit) {
832 bExit = TRUE;
833 }
834 }
835
OnPopupPostOpen(void * pPrivateData,FX_BOOL & bExit,FX_DWORD nFlag)836 void CFFL_IFormFiller::OnPopupPostOpen(void* pPrivateData,
837 FX_BOOL& bExit,
838 FX_DWORD nFlag) {
839 ASSERT(pPrivateData != NULL);
840 CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
841 ASSERT(pData->pWidget != NULL);
842
843 FX_BOOL bTempReset = FALSE;
844 FX_BOOL bTempExit = FALSE;
845 this->OnPostOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit,
846 nFlag);
847
848 if (bTempReset || bTempExit) {
849 bExit = TRUE;
850 }
851 }
852
OnPreOpen(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bReset,FX_BOOL & bExit,FX_UINT nFlag)853 void CFFL_IFormFiller::OnPreOpen(CPDFSDK_Widget* pWidget,
854 CPDFSDK_PageView* pPageView,
855 FX_BOOL& bReset,
856 FX_BOOL& bExit,
857 FX_UINT nFlag) {
858 ASSERT(pWidget != NULL);
859
860 if (!m_bNotifying) {
861 if (pWidget->HasXFAAAction(PDFSDK_XFA_PreOpen)) {
862 m_bNotifying = TRUE;
863 int nAge = pWidget->GetAppearanceAge();
864 int nValueAge = pWidget->GetValueAge();
865
866 PDFSDK_FieldAction fa;
867 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
868 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
869
870 pWidget->OnXFAAAction(PDFSDK_XFA_PreOpen, fa, pPageView);
871 m_bNotifying = FALSE;
872
873 if (!IsValidAnnot(pPageView, pWidget)) {
874 bExit = TRUE;
875 return;
876 }
877
878 if (nAge != pWidget->GetAppearanceAge()) {
879 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
880 pFormFiller->ResetPDFWindow(pPageView,
881 nValueAge == pWidget->GetValueAge());
882 }
883
884 bReset = TRUE;
885 }
886 }
887 }
888 }
889
OnPostOpen(CPDFSDK_Widget * pWidget,CPDFSDK_PageView * pPageView,FX_BOOL & bReset,FX_BOOL & bExit,FX_UINT nFlag)890 void CFFL_IFormFiller::OnPostOpen(CPDFSDK_Widget* pWidget,
891 CPDFSDK_PageView* pPageView,
892 FX_BOOL& bReset,
893 FX_BOOL& bExit,
894 FX_UINT nFlag) {
895 ASSERT(pWidget != NULL);
896
897 if (!m_bNotifying) {
898 if (pWidget->HasXFAAAction(PDFSDK_XFA_PostOpen)) {
899 m_bNotifying = TRUE;
900 int nAge = pWidget->GetAppearanceAge();
901 int nValueAge = pWidget->GetValueAge();
902
903 PDFSDK_FieldAction fa;
904 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
905 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
906
907 pWidget->OnXFAAAction(PDFSDK_XFA_PostOpen, fa, pPageView);
908 m_bNotifying = FALSE;
909
910 if (!IsValidAnnot(pPageView, pWidget)) {
911 bExit = TRUE;
912 return;
913 }
914
915 if (nAge != pWidget->GetAppearanceAge()) {
916 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
917 pFormFiller->ResetPDFWindow(pPageView,
918 nValueAge == pWidget->GetValueAge());
919 }
920
921 bReset = TRUE;
922 }
923 }
924 }
925 }
926 #endif // PDF_ENABLE_XFA
927
IsValidAnnot(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)928 FX_BOOL CFFL_IFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView,
929 CPDFSDK_Annot* pAnnot) {
930 if (pPageView)
931 return pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
932
933 return FALSE;
934 }
935
OnBeforeKeyStroke(void * pPrivateData,CFX_WideString & strChange,const CFX_WideString & strChangeEx,int nSelStart,int nSelEnd,FX_BOOL bKeyDown,FX_BOOL & bRC,FX_BOOL & bExit,FX_DWORD nFlag)936 void CFFL_IFormFiller::OnBeforeKeyStroke(void* pPrivateData,
937 CFX_WideString& strChange,
938 const CFX_WideString& strChangeEx,
939 int nSelStart,
940 int nSelEnd,
941 FX_BOOL bKeyDown,
942 FX_BOOL& bRC,
943 FX_BOOL& bExit,
944 FX_DWORD nFlag) {
945 CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
946 ASSERT(pData->pWidget);
947
948 CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
949
950 #ifdef PDF_ENABLE_XFA
951 if (pFormFiller->IsFieldFull(pData->pPageView)) {
952 FX_BOOL bFullExit = FALSE;
953 FX_BOOL bFullReset = FALSE;
954 OnFull(pData->pWidget, pData->pPageView, bFullReset, bFullExit, nFlag);
955
956 if (bFullReset || bFullExit) {
957 bExit = TRUE;
958 return;
959 }
960 }
961 #endif // PDF_ENABLE_XFA
962
963 if (!m_bNotifying) {
964 if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke)) {
965 m_bNotifying = TRUE;
966 int nAge = pData->pWidget->GetAppearanceAge();
967 int nValueAge = pData->pWidget->GetValueAge();
968
969 CPDFSDK_Document* pDocument = pData->pPageView->GetSDKDocument();
970
971 PDFSDK_FieldAction fa;
972 fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
973 fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
974 fa.sChange = strChange;
975 fa.sChangeEx = strChangeEx;
976 fa.bKeyDown = bKeyDown;
977 fa.bWillCommit = FALSE;
978 fa.bRC = TRUE;
979 fa.nSelStart = nSelStart;
980 fa.nSelEnd = nSelEnd;
981
982 pFormFiller->GetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
983 pFormFiller->SaveState(pData->pPageView);
984
985 if (pData->pWidget->OnAAction(CPDF_AAction::KeyStroke, fa,
986 pData->pPageView)) {
987 if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
988 bExit = TRUE;
989 m_bNotifying = FALSE;
990 return;
991 }
992
993 if (nAge != pData->pWidget->GetAppearanceAge()) {
994 CPWL_Wnd* pWnd = pFormFiller->ResetPDFWindow(
995 pData->pPageView, nValueAge == pData->pWidget->GetValueAge());
996 pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
997 bExit = TRUE;
998 }
999
1000 if (fa.bRC) {
1001 pFormFiller->SetActionData(pData->pPageView, CPDF_AAction::KeyStroke,
1002 fa);
1003 bRC = FALSE;
1004 } else {
1005 pFormFiller->RestoreState(pData->pPageView);
1006 bRC = FALSE;
1007 }
1008
1009 if (pDocument->GetFocusAnnot() != pData->pWidget) {
1010 pFormFiller->CommitData(pData->pPageView, nFlag);
1011 bExit = TRUE;
1012 }
1013 } else {
1014 if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
1015 bExit = TRUE;
1016 m_bNotifying = FALSE;
1017 return;
1018 }
1019 }
1020
1021 m_bNotifying = FALSE;
1022 }
1023 }
1024 }
1025