Clean up CPDF_AnnotList.
[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     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     pFormFiller->KillFocusForAnnot(pAnnot, nFlag);
474
475     if (!m_bNotifying) {
476       CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
477       if (pWidget->GetAAction(CPDF_AAction::LoseFocus)) {
478         m_bNotifying = TRUE;
479         pWidget->ClearAppModified();
480
481         CPDFSDK_PageView* pPageView = pWidget->GetPageView();
482         ASSERT(pPageView != NULL);
483
484         PDFSDK_FieldAction fa;
485         fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
486         fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
487
488         pFormFiller->GetActionData(pPageView, CPDF_AAction::LoseFocus, fa);
489
490         pWidget->OnAAction(CPDF_AAction::LoseFocus, fa, pPageView);
491         m_bNotifying = FALSE;
492       }
493     }
494   }
495
496   return TRUE;
497 }
498
499 FX_BOOL CFFL_IFormFiller::IsVisible(CPDFSDK_Widget* pWidget) {
500   return pWidget->IsVisible();
501 }
502
503 FX_BOOL CFFL_IFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget) {
504   ASSERT(pWidget != NULL);
505
506   int nFieldFlags = pWidget->GetFieldFlags();
507
508   return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
509 }
510
511 FX_BOOL CFFL_IFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget) {
512   if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
513     return TRUE;
514
515   CPDF_Page* pPage = pWidget->GetPDFPage();
516   CPDF_Document* pDocument = pPage->m_pDocument;
517   FX_DWORD dwPermissions = pDocument->GetUserPermissions();
518   return (dwPermissions & FPDFPERM_FILL_FORM) ||
519          (dwPermissions & FPDFPERM_ANNOT_FORM) ||
520          (dwPermissions & FPDFPERM_MODIFY);
521 }
522
523 CFFL_FormFiller* CFFL_IFormFiller::GetFormFiller(CPDFSDK_Annot* pAnnot,
524                                                  FX_BOOL bRegister) {
525   auto it = m_Maps.find(pAnnot);
526   if (it != m_Maps.end())
527     return it->second;
528
529   if (!bRegister)
530     return nullptr;
531
532   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
533   int nFieldType = pWidget->GetFieldType();
534   CFFL_FormFiller* pFormFiller;
535   switch (nFieldType) {
536     case FIELDTYPE_PUSHBUTTON:
537       pFormFiller = new CFFL_PushButton(m_pApp, pWidget);
538       break;
539     case FIELDTYPE_CHECKBOX:
540       pFormFiller = new CFFL_CheckBox(m_pApp, pWidget);
541       break;
542     case FIELDTYPE_RADIOBUTTON:
543       pFormFiller = new CFFL_RadioButton(m_pApp, pWidget);
544       break;
545     case FIELDTYPE_TEXTFIELD:
546       pFormFiller = new CFFL_TextField(m_pApp, pWidget);
547       break;
548     case FIELDTYPE_LISTBOX:
549       pFormFiller = new CFFL_ListBox(m_pApp, pWidget);
550       break;
551     case FIELDTYPE_COMBOBOX:
552       pFormFiller = new CFFL_ComboBox(m_pApp, pWidget);
553       break;
554     case FIELDTYPE_UNKNOWN:
555     default:
556       pFormFiller = nullptr;
557       break;
558   }
559
560   if (!pFormFiller)
561     return nullptr;
562
563   m_Maps[pAnnot] = pFormFiller;
564   return pFormFiller;
565 }
566
567 void CFFL_IFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot) {
568   if (pAnnot != NULL) {
569     UnRegisterFormFiller(pAnnot);
570   }
571 }
572
573 void CFFL_IFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot) {
574   auto it = m_Maps.find(pAnnot);
575   if (it == m_Maps.end())
576     return;
577
578   delete it->second;
579   m_Maps.erase(it);
580 }
581
582 void CFFL_IFormFiller::QueryWherePopup(void* pPrivateData,
583                                        FX_FLOAT fPopupMin,
584                                        FX_FLOAT fPopupMax,
585                                        int32_t& nRet,
586                                        FX_FLOAT& fPopupRet) {
587   ASSERT(pPrivateData != NULL);
588
589   CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
590
591   CPDF_Rect rcPageView(0, 0, 0, 0);
592   rcPageView.right = pData->pWidget->GetPDFPage()->GetPageWidth();
593   rcPageView.bottom = pData->pWidget->GetPDFPage()->GetPageHeight();
594   rcPageView.Normalize();
595
596   ASSERT(pData->pWidget != NULL);
597   CPDF_Rect rcAnnot = pData->pWidget->GetRect();
598
599   FX_FLOAT fTop = 0.0f;
600   FX_FLOAT fBottom = 0.0f;
601
602   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pData->pWidget;
603   switch (pWidget->GetRotate() / 90) {
604     default:
605     case 0:
606       fTop = rcPageView.top - rcAnnot.top;
607       fBottom = rcAnnot.bottom - rcPageView.bottom;
608       break;
609     case 1:
610       fTop = rcAnnot.left - rcPageView.left;
611       fBottom = rcPageView.right - rcAnnot.right;
612       break;
613     case 2:
614       fTop = rcAnnot.bottom - rcPageView.bottom;
615       fBottom = rcPageView.top - rcAnnot.top;
616       break;
617     case 3:
618       fTop = rcPageView.right - rcAnnot.right;
619       fBottom = rcAnnot.left - rcPageView.left;
620       break;
621   }
622
623   FX_FLOAT fFactHeight = 0;
624   FX_BOOL bBottom = TRUE;
625   FX_FLOAT fMaxListBoxHeight = 0;
626   if (fPopupMax > FFL_MAXLISTBOXHEIGHT) {
627     if (fPopupMin > FFL_MAXLISTBOXHEIGHT) {
628       fMaxListBoxHeight = fPopupMin;
629     } else {
630       fMaxListBoxHeight = FFL_MAXLISTBOXHEIGHT;
631     }
632   } else
633     fMaxListBoxHeight = fPopupMax;
634
635   if (fBottom > fMaxListBoxHeight) {
636     fFactHeight = fMaxListBoxHeight;
637     bBottom = TRUE;
638   } else {
639     if (fTop > fMaxListBoxHeight) {
640       fFactHeight = fMaxListBoxHeight;
641       bBottom = FALSE;
642     } else {
643       if (fTop > fBottom) {
644         fFactHeight = fTop;
645         bBottom = FALSE;
646       } else {
647         fFactHeight = fBottom;
648         bBottom = TRUE;
649       }
650     }
651   }
652
653   nRet = bBottom ? 0 : 1;
654   fPopupRet = fFactHeight;
655 }
656
657 void CFFL_IFormFiller::OnKeyStrokeCommit(CPDFSDK_Widget* pWidget,
658                                          CPDFSDK_PageView* pPageView,
659                                          FX_BOOL& bRC,
660                                          FX_BOOL& bExit,
661                                          FX_DWORD nFlag) {
662   if (!m_bNotifying) {
663     ASSERT(pWidget != NULL);
664     if (pWidget->GetAAction(CPDF_AAction::KeyStroke)) {
665       m_bNotifying = TRUE;
666       pWidget->ClearAppModified();
667
668       ASSERT(pPageView != NULL);
669
670       PDFSDK_FieldAction fa;
671       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
672       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
673       fa.bWillCommit = TRUE;
674       fa.bKeyDown = TRUE;
675       fa.bRC = TRUE;
676
677       CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
678       ASSERT(pFormFiller != NULL);
679
680       pFormFiller->GetActionData(pPageView, CPDF_AAction::KeyStroke, fa);
681       pFormFiller->SaveState(pPageView);
682
683       PDFSDK_FieldAction faOld = fa;
684       pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pPageView);
685
686       bRC = fa.bRC;
687       //          bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView,
688       //          pWidget);
689
690       m_bNotifying = FALSE;
691     }
692   }
693 }
694
695 void CFFL_IFormFiller::OnValidate(CPDFSDK_Widget* pWidget,
696                                   CPDFSDK_PageView* pPageView,
697                                   FX_BOOL& bRC,
698                                   FX_BOOL& bExit,
699                                   FX_DWORD nFlag) {
700   if (!m_bNotifying) {
701     ASSERT(pWidget != NULL);
702     if (pWidget->GetAAction(CPDF_AAction::Validate)) {
703       m_bNotifying = TRUE;
704       pWidget->ClearAppModified();
705
706       ASSERT(pPageView != NULL);
707       //          CReader_DocView* pDocView = pPageView->GetDocView();
708       //          ASSERT(pDocView != NULL);
709
710       PDFSDK_FieldAction fa;
711       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
712       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
713       fa.bKeyDown = TRUE;
714       fa.bRC = TRUE;
715
716       CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
717       ASSERT(pFormFiller != NULL);
718
719       pFormFiller->GetActionData(pPageView, CPDF_AAction::Validate, fa);
720       pFormFiller->SaveState(pPageView);
721
722       PDFSDK_FieldAction faOld = fa;
723       pWidget->OnAAction(CPDF_AAction::Validate, fa, pPageView);
724
725       bRC = fa.bRC;
726       //          bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView,
727       //          pWidget);
728
729       m_bNotifying = FALSE;
730     }
731   }
732 }
733
734 void CFFL_IFormFiller::OnCalculate(CPDFSDK_Widget* pWidget,
735                                    CPDFSDK_PageView* pPageView,
736                                    FX_BOOL& bExit,
737                                    FX_DWORD nFlag) {
738   if (!m_bNotifying) {
739     ASSERT(pWidget != NULL);
740     ASSERT(pPageView != NULL);
741     //      CReader_DocView* pDocView = pPageView->GetDocView();
742     //      ASSERT(pDocView != NULL);
743     CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
744     ASSERT(pDocument != NULL);
745
746     CPDFSDK_InterForm* pInterForm =
747         (CPDFSDK_InterForm*)pDocument->GetInterForm();
748     ASSERT(pInterForm != NULL);
749
750     pInterForm->OnCalculate(pWidget->GetFormField());
751
752     //      bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView,
753     //      pWidget);
754
755     m_bNotifying = FALSE;
756   }
757 }
758
759 void CFFL_IFormFiller::OnFormat(CPDFSDK_Widget* pWidget,
760                                 CPDFSDK_PageView* pPageView,
761                                 FX_BOOL& bExit,
762                                 FX_DWORD nFlag) {
763   if (!m_bNotifying) {
764     ASSERT(pWidget != NULL);
765     ASSERT(pPageView != NULL);
766     //      CReader_DocView* pDocView = pPageView->GetDocView();
767     //      ASSERT(pDocView != NULL);
768     CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
769     ASSERT(pDocument != NULL);
770
771     CPDFSDK_InterForm* pInterForm =
772         (CPDFSDK_InterForm*)pDocument->GetInterForm();
773     ASSERT(pInterForm != NULL);
774
775     FX_BOOL bFormated = FALSE;
776     CFX_WideString sValue =
777         pInterForm->OnFormat(pWidget->GetFormField(), bFormated);
778
779     //      bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView,
780     //      pWidget);
781
782     if (bExit)
783       return;
784
785     if (bFormated) {
786       pInterForm->ResetFieldAppearance(pWidget->GetFormField(), sValue.c_str(),
787                                        TRUE);
788       pInterForm->UpdateField(pWidget->GetFormField());
789     }
790
791     m_bNotifying = FALSE;
792   }
793 }
794
795 FX_BOOL CFFL_IFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView,
796                                        CPDFSDK_Annot* pAnnot) {
797   if (pPageView)
798     return pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
799
800   return FALSE;
801 }
802
803 void CFFL_IFormFiller::OnBeforeKeyStroke(void* pPrivateData,
804                                          CFX_WideString& strChange,
805                                          const CFX_WideString& strChangeEx,
806                                          int nSelStart,
807                                          int nSelEnd,
808                                          FX_BOOL bKeyDown,
809                                          FX_BOOL& bRC,
810                                          FX_BOOL& bExit,
811                                          FX_DWORD nFlag) {
812   ASSERT(pPrivateData != NULL);
813   CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
814   ASSERT(pData->pWidget != NULL);
815
816   CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
817   ASSERT(pFormFiller != NULL);
818
819   if (!m_bNotifying) {
820     if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke)) {
821       m_bNotifying = TRUE;
822       int nAge = pData->pWidget->GetAppearanceAge();
823       int nValueAge = pData->pWidget->GetValueAge();
824
825       ASSERT(pData->pPageView != NULL);
826       CPDFSDK_Document* pDocument = pData->pPageView->GetSDKDocument();
827
828       PDFSDK_FieldAction fa;
829       fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
830       fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
831       fa.sChange = strChange;
832       fa.sChangeEx = strChangeEx;
833       fa.bKeyDown = bKeyDown;
834       fa.bWillCommit = FALSE;
835       fa.bRC = TRUE;
836       fa.nSelStart = nSelStart;
837       fa.nSelEnd = nSelEnd;
838
839       pFormFiller->GetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
840       pFormFiller->SaveState(pData->pPageView);
841
842       if (pData->pWidget->OnAAction(CPDF_AAction::KeyStroke, fa,
843                                     pData->pPageView)) {
844         if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
845           bExit = TRUE;
846           m_bNotifying = FALSE;
847           return;
848         }
849
850         if (nAge != pData->pWidget->GetAppearanceAge()) {
851           CPWL_Wnd* pWnd = pFormFiller->ResetPDFWindow(
852               pData->pPageView, nValueAge == pData->pWidget->GetValueAge());
853           pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
854           bExit = TRUE;
855         }
856
857         if (fa.bRC) {
858           pFormFiller->SetActionData(pData->pPageView, CPDF_AAction::KeyStroke,
859                                      fa);
860           bRC = FALSE;
861         } else {
862           pFormFiller->RestoreState(pData->pPageView);
863           bRC = FALSE;
864         }
865
866         if (pDocument->GetFocusAnnot() != pData->pWidget) {
867           pFormFiller->CommitData(pData->pPageView, nFlag);
868           bExit = TRUE;
869         }
870       } else {
871         if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
872           bExit = TRUE;
873           m_bNotifying = FALSE;
874           return;
875         }
876       }
877
878       m_bNotifying = FALSE;
879     }
880   }
881 }