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
21CFFL_IFormFiller::CFFL_IFormFiller(CPDFDoc_Environment* pApp)
22    : m_pApp(pApp), m_bNotifying(FALSE) {}
23
24CFFL_IFormFiller::~CFFL_IFormFiller() {
25  for (auto& it : m_Maps)
26    delete it.second;
27  m_Maps.clear();
28}
29
30FX_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
39FX_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
54void 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
104void CFFL_IFormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {
105  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
106    pFormFiller->OnCreate(pAnnot);
107  }
108}
109
110void CFFL_IFormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {
111  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
112    pFormFiller->OnLoad(pAnnot);
113  }
114}
115
116void 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
124void 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
160void 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
196FX_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
238FX_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
279void 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
318FX_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
331FX_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
345FX_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
359FX_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
372FX_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
385FX_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
397FX_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
410FX_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
454FX_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
486FX_BOOL CFFL_IFormFiller::IsVisible(CPDFSDK_Widget* pWidget) {
487  return pWidget->IsVisible();
488}
489
490FX_BOOL CFFL_IFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget) {
491  int nFieldFlags = pWidget->GetFieldFlags();
492  return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
493}
494
495FX_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
507CFFL_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
551void CFFL_IFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot) {
552  if (pAnnot) {
553    UnRegisterFormFiller(pAnnot);
554  }
555}
556
557void 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
566void 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
639void 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
671void 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
702void 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
717void 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
745void 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
782void 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
819void 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
836void 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
853void 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
890void 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
928FX_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
936void 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