clang-format all pdfium code.
[pdfium.git] / fpdfsdk / src / formfiller / FFL_FormFiller.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_Notify.h"
9 #include "../../include/formfiller/FFL_CBA_Fontmap.h"
10
11 #define GetRed(rgb) ((uint8_t)(rgb))
12 #define GetGreen(rgb) ((uint8_t)(((FX_WORD)(rgb)) >> 8))
13 #define GetBlue(rgb) ((uint8_t)((rgb) >> 16))
14
15 #define FFL_HINT_ELAPSE 800
16
17 /* ------------------------- CFFL_FormFiller ------------------------- */
18
19 CFFL_FormFiller::CFFL_FormFiller(CPDFDoc_Environment* pApp,
20                                  CPDFSDK_Annot* pAnnot)
21     : m_pApp(pApp), m_pAnnot(pAnnot), m_bValid(FALSE), m_ptOldPos(0, 0) {
22   m_pWidget = (CPDFSDK_Widget*)pAnnot;
23 }
24
25 CFFL_FormFiller::~CFFL_FormFiller() {
26   for (auto& it : m_Maps) {
27     CPWL_Wnd* pWnd = it.second;
28     CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
29     pWnd->Destroy();
30     delete pWnd;
31     delete pData;
32   }
33   m_Maps.clear();
34 }
35
36 void CFFL_FormFiller::SetWindowRect(CPDFSDK_PageView* pPageView,
37                                     const CPDF_Rect& rcWindow) {
38   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
39     pWnd->Move(CPDF_Rect(rcWindow), TRUE, FALSE);
40   }
41 }
42
43 CPDF_Rect CFFL_FormFiller::GetWindowRect(CPDFSDK_PageView* pPageView) {
44   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
45     return pWnd->GetWindowRect();
46   }
47
48   return CPDF_Rect(0, 0, 0, 0);
49 }
50
51 FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
52                                      CPDFSDK_Annot* pAnnot) {
53   ASSERT(pPageView != NULL);
54   ASSERT(pAnnot != NULL);
55
56   CPDF_Rect rcAnnot = m_pWidget->GetRect();
57
58   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
59     CPDF_Rect rcWindow = pWnd->GetWindowRect();
60     rcAnnot = PWLtoFFL(rcWindow);
61   }
62
63   CPDF_Rect rcWin = rcAnnot;
64
65   CPDF_Rect rcFocus = GetFocusBox(pPageView);
66   if (!rcFocus.IsEmpty())
67     rcWin.Union(rcFocus);
68
69   CPDF_Rect rect = CPWL_Utils::InflateRect(rcWin, 1);
70
71   return rect.GetOutterRect();
72 }
73
74 void CFFL_FormFiller::OnDraw(CPDFSDK_PageView* pPageView,
75                              CPDFSDK_Annot* pAnnot,
76                              CFX_RenderDevice* pDevice,
77                              CPDF_Matrix* pUser2Device,
78                              FX_DWORD dwFlags) {
79   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
80
81   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
82     CPDF_Matrix mt = GetCurMatrix();
83     mt.Concat(*pUser2Device);
84     pWnd->DrawAppearance(pDevice, &mt);
85   } else {
86     CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
87     if (CFFL_IFormFiller::IsVisible(pWidget))
88       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
89   }
90 }
91
92 void CFFL_FormFiller::OnDrawDeactive(CPDFSDK_PageView* pPageView,
93                                      CPDFSDK_Annot* pAnnot,
94                                      CFX_RenderDevice* pDevice,
95                                      CPDF_Matrix* pUser2Device,
96                                      FX_DWORD dwFlags) {
97   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
98   pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
99 }
100
101 void CFFL_FormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {}
102
103 void CFFL_FormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {}
104
105 void CFFL_FormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {}
106
107 void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
108                                    CPDFSDK_Annot* pAnnot) {}
109
110 void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
111                                   CPDFSDK_Annot* pAnnot) {
112   EndTimer();
113   ASSERT(m_pWidget != NULL);
114 }
115
116 FX_BOOL CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
117                                        CPDFSDK_Annot* pAnnot,
118                                        FX_UINT nFlags,
119                                        const CPDF_Point& point) {
120   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
121     m_bValid = TRUE;
122     FX_RECT rect = GetViewBBox(pPageView, pAnnot);
123     InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
124
125     if (!rect.Contains((int)point.x, (int)point.y))
126       return FALSE;
127
128     return pWnd->OnLButtonDown(WndtoPWL(pPageView, point), nFlags);
129   }
130
131   return FALSE;
132 }
133
134 FX_BOOL CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
135                                      CPDFSDK_Annot* pAnnot,
136                                      FX_UINT nFlags,
137                                      const CPDF_Point& point) {
138   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
139     FX_RECT rcFFL = GetViewBBox(pPageView, pAnnot);
140     InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom);
141     pWnd->OnLButtonUp(WndtoPWL(pPageView, point), nFlags);
142     return TRUE;
143   }
144
145   return FALSE;
146 }
147
148 FX_BOOL CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
149                                          CPDFSDK_Annot* pAnnot,
150                                          FX_UINT nFlags,
151                                          const CPDF_Point& point) {
152   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
153     pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point), nFlags);
154     return TRUE;
155   }
156
157   return FALSE;
158 }
159
160 FX_BOOL CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
161                                      CPDFSDK_Annot* pAnnot,
162                                      FX_UINT nFlags,
163                                      const CPDF_Point& point) {
164   if ((m_ptOldPos.x != point.x) || (m_ptOldPos.y != point.y)) {
165     m_ptOldPos = point;
166   }
167
168   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
169     pWnd->OnMouseMove(WndtoPWL(pPageView, point), nFlags);
170     return TRUE;
171   }
172
173   return FALSE;
174 }
175
176 FX_BOOL CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
177                                       CPDFSDK_Annot* pAnnot,
178                                       FX_UINT nFlags,
179                                       short zDelta,
180                                       const CPDF_Point& point) {
181   if (!IsValid())
182     return FALSE;
183
184   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
185     return pWnd->OnMouseWheel(zDelta, WndtoPWL(pPageView, point), nFlags);
186   }
187
188   return FALSE;
189 }
190
191 FX_BOOL CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
192                                        CPDFSDK_Annot* pAnnot,
193                                        FX_UINT nFlags,
194                                        const CPDF_Point& point) {
195   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
196     pWnd->OnRButtonDown(WndtoPWL(pPageView, point), nFlags);
197     return TRUE;
198   }
199
200   return FALSE;
201 }
202
203 FX_BOOL CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
204                                      CPDFSDK_Annot* pAnnot,
205                                      FX_UINT nFlags,
206                                      const CPDF_Point& point) {
207   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
208     pWnd->OnRButtonUp(WndtoPWL(pPageView, point), nFlags);
209     return TRUE;
210   }
211
212   return FALSE;
213 }
214
215 FX_BOOL CFFL_FormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
216                                    FX_UINT nKeyCode,
217                                    FX_UINT nFlags) {
218   if (IsValid()) {
219     CPDFSDK_PageView* pPageView = GetCurPageView();
220     ASSERT(pPageView != NULL);
221
222     if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
223       return pWnd->OnKeyDown(nKeyCode, nFlags);
224     }
225   }
226
227   return FALSE;
228 }
229
230 FX_BOOL CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot,
231                                 FX_UINT nChar,
232                                 FX_UINT nFlags) {
233   if (IsValid()) {
234     CPDFSDK_PageView* pPageView = GetCurPageView();
235     ASSERT(pPageView != NULL);
236
237     if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
238       return pWnd->OnChar(nChar, nFlags);
239     }
240   }
241
242   return FALSE;
243 }
244
245 FX_BOOL CFFL_FormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
246   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
247   CPDF_Page* pPage = pWidget->GetPDFPage();
248   CPDFSDK_Document* pDoc = m_pApp->GetSDKDocument();
249   CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage);
250   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
251     pWnd->SetFocus();
252
253   m_bValid = TRUE;
254   FX_RECT rcRect = GetViewBBox(pPageView, pAnnot);
255   InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
256   return TRUE;
257 }
258
259 FX_BOOL CFFL_FormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
260   if (!IsValid())
261     return TRUE;
262
263   CPDFSDK_PageView* pPageView = GetCurPageView();
264   CommitData(pPageView, nFlag);
265
266   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE))
267     pWnd->KillFocus();
268
269   switch (m_pWidget->GetFieldType()) {
270     case FIELDTYPE_PUSHBUTTON:
271     case FIELDTYPE_CHECKBOX:
272     case FIELDTYPE_RADIOBUTTON:
273       EscapeFiller(pPageView, TRUE);
274       break;
275     default:
276       EscapeFiller(pPageView, FALSE);
277       break;
278   }
279   return TRUE;
280 }
281
282 FX_BOOL CFFL_FormFiller::IsValid() const {
283   return m_bValid;
284 }
285
286 PWL_CREATEPARAM CFFL_FormFiller::GetCreateParam() {
287   ASSERT(m_pApp != NULL);
288
289   PWL_CREATEPARAM cp;
290   cp.pParentWnd = NULL;
291   cp.pProvider = this;
292   cp.rcRectWnd = GetPDFWindowRect();
293
294   FX_DWORD dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
295   FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
296   if (dwFieldFlag & FIELDFLAG_READONLY) {
297     dwCreateFlags |= PWS_READONLY;
298   }
299
300   FX_COLORREF color;
301   if (m_pWidget->GetFillColor(color)) {
302     cp.sBackgroundColor =
303         CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
304   }
305
306   if (m_pWidget->GetBorderColor(color)) {
307     cp.sBorderColor =
308         CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
309   }
310
311   cp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);
312
313   if (m_pWidget->GetTextColor(color)) {
314     cp.sTextColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
315   }
316
317   cp.fFontSize = m_pWidget->GetFontSize();
318   cp.dwBorderWidth = m_pWidget->GetBorderWidth();
319
320   int nBorderStyle = m_pWidget->GetBorderStyle();
321
322   switch (nBorderStyle) {
323     case BBS_SOLID:
324       cp.nBorderStyle = PBS_SOLID;
325       break;
326     case BBS_DASH:
327       cp.nBorderStyle = PBS_DASH;
328       cp.sDash = CPWL_Dash(3, 3, 0);
329       break;
330     case BBS_BEVELED:
331       cp.nBorderStyle = PBS_BEVELED;
332       cp.dwBorderWidth *= 2;
333       break;
334     case BBS_INSET:
335       cp.nBorderStyle = PBS_INSET;
336       cp.dwBorderWidth *= 2;
337       break;
338     case BBS_UNDERLINE:
339       cp.nBorderStyle = PBS_UNDERLINED;
340       break;
341   }
342
343   if (cp.fFontSize <= 0) {
344     dwCreateFlags |= PWS_AUTOFONTSIZE;
345   }
346
347   cp.dwFlags = dwCreateFlags;
348   cp.pSystemHandler = m_pApp->GetSysHandler();
349   return cp;
350 }
351
352 CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView,
353                                         FX_BOOL bNew) {
354   ASSERT(pPageView);
355
356   auto it = m_Maps.find(pPageView);
357   const bool found = it != m_Maps.end();
358   CPWL_Wnd* pWnd = found ? it->second : nullptr;
359   if (!bNew)
360     return pWnd;
361
362   if (found) {
363     CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pWnd->GetAttachedData();
364     if (pPrivateData->nWidgetAge != m_pWidget->GetAppearanceAge()) {
365       return ResetPDFWindow(
366           pPageView, m_pWidget->GetValueAge() == pPrivateData->nValueAge);
367     }
368   } else {
369     PWL_CREATEPARAM cp = GetCreateParam();
370     cp.hAttachedWnd = (FX_HWND)m_pWidget;
371
372     CFFL_PrivateData* pPrivateData = new CFFL_PrivateData;
373     pPrivateData->pWidget = m_pWidget;
374     pPrivateData->pPageView = pPageView;
375     pPrivateData->nWidgetAge = m_pWidget->GetAppearanceAge();
376     pPrivateData->nValueAge = 0;
377
378     cp.pAttachedData = pPrivateData;
379
380     pWnd = NewPDFWindow(cp, pPageView);
381     m_Maps[pPageView] = pWnd;
382   }
383
384   return pWnd;
385 }
386
387 void CFFL_FormFiller::DestroyPDFWindow(CPDFSDK_PageView* pPageView) {
388   auto it = m_Maps.find(pPageView);
389   if (it == m_Maps.end())
390     return;
391
392   CPWL_Wnd* pWnd = it->second;
393   CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
394   pWnd->Destroy();
395   delete pWnd;
396   delete pData;
397
398   m_Maps.erase(it);
399 }
400
401 CPDF_Matrix CFFL_FormFiller::GetWindowMatrix(void* pAttachedData) {
402   if (CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pAttachedData) {
403     if (pPrivateData->pPageView) {
404       CPDF_Matrix mtPageView;
405       pPrivateData->pPageView->GetCurrentMatrix(mtPageView);
406       CPDF_Matrix mt = GetCurMatrix();
407       mt.Concat(mtPageView);
408
409       return mt;
410     }
411   }
412   return CPDF_Matrix(1, 0, 0, 1, 0, 0);
413 }
414
415 CPDF_Matrix CFFL_FormFiller::GetCurMatrix() {
416   CPDF_Matrix mt;
417
418   ASSERT(m_pWidget != NULL);
419
420   CPDF_Rect rcDA;
421   m_pWidget->GetPDFAnnot()->GetRect(rcDA);
422
423   switch (m_pWidget->GetRotate()) {
424     default:
425     case 0:
426       mt = CPDF_Matrix(1, 0, 0, 1, 0, 0);
427       break;
428     case 90:
429       mt = CPDF_Matrix(0, 1, -1, 0, rcDA.right - rcDA.left, 0);
430       break;
431     case 180:
432       mt = CPDF_Matrix(-1, 0, 0, -1, rcDA.right - rcDA.left,
433                        rcDA.top - rcDA.bottom);
434       break;
435     case 270:
436       mt = CPDF_Matrix(0, -1, 1, 0, 0, rcDA.top - rcDA.bottom);
437       break;
438   }
439   mt.e += rcDA.left;
440   mt.f += rcDA.bottom;
441
442   return mt;
443 }
444
445 CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
446   ASSERT(m_pApp != NULL);
447
448   return L"";
449 }
450
451 CPDF_Rect CFFL_FormFiller::GetPDFWindowRect() const {
452   CPDF_Rect rectAnnot;
453   m_pWidget->GetPDFAnnot()->GetRect(rectAnnot);
454
455   FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
456   FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
457   if ((m_pWidget->GetRotate() / 90) & 0x01)
458     return CPDF_Rect(0, 0, fHeight, fWidth);
459
460   return CPDF_Rect(0, 0, fWidth, fHeight);
461 }
462
463 CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView() {
464   CPDF_Page* pPage = m_pAnnot->GetPDFPage();
465   CPDFSDK_Document* pSDKDoc = m_pApp->GetSDKDocument();
466   return pSDKDoc ? pSDKDoc->GetPageView(pPage) : nullptr;
467 }
468
469 CPDF_Rect CFFL_FormFiller::GetFocusBox(CPDFSDK_PageView* pPageView) {
470   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
471     CPDF_Rect rcFocus = FFLtoWnd(pPageView, PWLtoFFL(pWnd->GetFocusRect()));
472     CPDF_Rect rcPage = pPageView->GetPDFPage()->GetPageBBox();
473     if (rcPage.Contains(rcFocus))
474       return rcFocus;
475   }
476   return CPDF_Rect(0, 0, 0, 0);
477 }
478
479 CPDF_Rect CFFL_FormFiller::FFLtoPWL(const CPDF_Rect& rect) {
480   CPDF_Matrix mt;
481   mt.SetReverse(GetCurMatrix());
482
483   CPDF_Rect temp = rect;
484   mt.TransformRect(temp);
485
486   return temp;
487 }
488
489 CPDF_Rect CFFL_FormFiller::PWLtoFFL(const CPDF_Rect& rect) {
490   CPDF_Matrix mt = GetCurMatrix();
491
492   CPDF_Rect temp = rect;
493   mt.TransformRect(temp);
494
495   return temp;
496 }
497
498 CPDF_Point CFFL_FormFiller::FFLtoPWL(const CPDF_Point& point) {
499   CPDF_Matrix mt;
500   mt.SetReverse(GetCurMatrix());
501
502   CPDF_Point pt = point;
503   mt.Transform(pt.x, pt.y);
504
505   return pt;
506 }
507
508 CPDF_Point CFFL_FormFiller::PWLtoFFL(const CPDF_Point& point) {
509   CPDF_Matrix mt = GetCurMatrix();
510
511   CPDF_Point pt = point;
512   mt.Transform(pt.x, pt.y);
513
514   return pt;
515 }
516
517 CPDF_Point CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
518                                      const CPDF_Point& pt) {
519   return FFLtoPWL(pt);
520 }
521
522 CPDF_Rect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
523                                     const CPDF_Rect& rect) {
524   return rect;
525 }
526
527 FX_BOOL CFFL_FormFiller::CommitData(CPDFSDK_PageView* pPageView,
528                                     FX_UINT nFlag) {
529   if (IsDataChanged(pPageView)) {
530     FX_BOOL bRC = TRUE;
531     FX_BOOL bExit = FALSE;
532     CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
533     pIFormFiller->OnKeyStrokeCommit(m_pWidget, pPageView, bRC, bExit, nFlag);
534     if (bExit)
535       return TRUE;
536     if (!bRC) {
537       ResetPDFWindow(pPageView, FALSE);
538       return TRUE;
539     }
540
541     pIFormFiller->OnValidate(m_pWidget, pPageView, bRC, bExit, nFlag);
542     if (bExit)
543       return TRUE;
544     if (!bRC) {
545       ResetPDFWindow(pPageView, FALSE);
546       return TRUE;
547     }
548
549     SaveData(pPageView);
550     pIFormFiller->OnCalculate(m_pWidget, pPageView, bExit, nFlag);
551     if (bExit)
552       return TRUE;
553
554     pIFormFiller->OnFormat(m_pWidget, pPageView, bExit, nFlag);
555   }
556   return TRUE;
557 }
558
559 FX_BOOL CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
560   return FALSE;
561 }
562
563 void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}
564
565 void CFFL_FormFiller::SetChangeMark() {
566   m_pApp->FFI_OnChange();
567 }
568
569 void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView,
570                                     CPDF_AAction::AActionType type,
571                                     PDFSDK_FieldAction& fa) {
572   fa.sValue = m_pWidget->GetValue();
573 }
574
575 void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
576                                     CPDF_AAction::AActionType type,
577                                     const PDFSDK_FieldAction& fa) {}
578
579 FX_BOOL CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type,
580                                              const PDFSDK_FieldAction& faOld,
581                                              const PDFSDK_FieldAction& faNew) {
582   return FALSE;
583 }
584
585 void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}
586
587 void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}
588
589 CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
590                                           FX_BOOL bRestoreValue) {
591   return GetPDFWindow(pPageView, FALSE);
592 }
593
594 void CFFL_FormFiller::TimerProc() {}
595
596 IFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
597   return m_pApp->GetSysHandler();
598 }
599
600 void CFFL_FormFiller::OnKeyStroke(FX_BOOL bKeyDown) {}
601
602 void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView,
603                                    FX_BOOL bDestroyPDFWindow) {
604   m_bValid = FALSE;
605
606   FX_RECT rcRect = GetViewBBox(pPageView, m_pWidget);
607   InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
608
609   if (bDestroyPDFWindow)
610     DestroyPDFWindow(pPageView);
611 }
612
613 FX_BOOL CFFL_FormFiller::CanCopy(CPDFSDK_Document* pDocument) {
614   return FALSE;
615 }
616
617 FX_BOOL CFFL_FormFiller::CanCut(CPDFSDK_Document* pDocument) {
618   return FALSE;
619 }
620
621 FX_BOOL CFFL_FormFiller::CanPaste(CPDFSDK_Document* pDocument) {
622   return FALSE;
623 }
624
625 void CFFL_FormFiller::DoCopy(CPDFSDK_Document* pDocument) {}
626
627 void CFFL_FormFiller::DoCut(CPDFSDK_Document* pDocument) {}
628
629 void CFFL_FormFiller::DoPaste(CPDFSDK_Document* pDocument) {}
630
631 void CFFL_FormFiller::InvalidateRect(double left,
632                                      double top,
633                                      double right,
634                                      double bottom) {
635   CPDF_Page* pPage = m_pWidget->GetPDFPage();
636   m_pApp->FFI_Invalidate(pPage, left, top, right, bottom);
637 }
638
639 /* ------------------------- CFFL_Button ------------------------- */
640
641 CFFL_Button::CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget)
642     : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(FALSE), m_bMouseDown(FALSE) {}
643
644 CFFL_Button::~CFFL_Button() {}
645
646 void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView,
647                                CPDFSDK_Annot* pAnnot) {
648   m_bMouseIn = TRUE;
649   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
650   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
651 }
652
653 void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView,
654                               CPDFSDK_Annot* pAnnot) {
655   m_bMouseIn = FALSE;
656
657   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
658   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
659   EndTimer();
660   ASSERT(m_pWidget != NULL);
661 }
662
663 FX_BOOL CFFL_Button::OnLButtonDown(CPDFSDK_PageView* pPageView,
664                                    CPDFSDK_Annot* pAnnot,
665                                    FX_UINT nFlags,
666                                    const CPDF_Point& point) {
667   CPDF_Rect rcAnnot = pAnnot->GetRect();
668   if (!rcAnnot.Contains(point.x, point.y))
669     return FALSE;
670
671   m_bMouseDown = TRUE;
672   m_bValid = TRUE;
673   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
674   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
675   return TRUE;
676 }
677
678 FX_BOOL CFFL_Button::OnLButtonUp(CPDFSDK_PageView* pPageView,
679                                  CPDFSDK_Annot* pAnnot,
680                                  FX_UINT nFlags,
681                                  const CPDF_Point& point) {
682   CPDF_Rect rcAnnot = pAnnot->GetRect();
683   if (!rcAnnot.Contains(point.x, point.y))
684     return FALSE;
685
686   m_bMouseDown = FALSE;
687   m_pWidget->GetPDFPage();
688
689   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
690   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
691   return TRUE;
692 }
693
694 FX_BOOL CFFL_Button::OnMouseMove(CPDFSDK_PageView* pPageView,
695                                  CPDFSDK_Annot* pAnnot,
696                                  FX_UINT nFlags,
697                                  const CPDF_Point& point) {
698   ASSERT(m_pApp != NULL);
699
700   return TRUE;
701 }
702
703 void CFFL_Button::OnDraw(CPDFSDK_PageView* pPageView,
704                          CPDFSDK_Annot* pAnnot,
705                          CFX_RenderDevice* pDevice,
706                          CPDF_Matrix* pUser2Device,
707                          FX_DWORD dwFlags) {
708   ASSERT(pPageView != NULL);
709   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
710   CPDF_FormControl* pCtrl = pWidget->GetFormControl();
711   CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();
712
713   if (eHM == CPDF_FormControl::Push) {
714     if (m_bMouseDown) {
715       if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
716         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, NULL);
717       else
718         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
719                                 NULL);
720     } else if (m_bMouseIn) {
721       if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
722         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover,
723                                 NULL);
724       else
725         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
726                                 NULL);
727     } else {
728       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
729     }
730   } else
731     pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
732 }
733
734 void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView* pPageView,
735                                  CPDFSDK_Annot* pAnnot,
736                                  CFX_RenderDevice* pDevice,
737                                  CPDF_Matrix* pUser2Device,
738                                  FX_DWORD dwFlags) {
739   OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
740 }