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