Cleanup: Mark methods with the override keyword.
[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::SetFocusForAnnot(CPDFSDK_Annot* pAnnot,
246                                           FX_UINT nFlag) {
247   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
248   CPDF_Page* pPage = pWidget->GetPDFPage();
249   CPDFSDK_Document* pDoc = m_pApp->GetSDKDocument();
250   CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage);
251   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
252     pWnd->SetFocus();
253
254   m_bValid = TRUE;
255   FX_RECT rcRect = GetViewBBox(pPageView, pAnnot);
256   InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
257   return TRUE;
258 }
259
260 FX_BOOL CFFL_FormFiller::KillFocusForAnnot(CPDFSDK_Annot* pAnnot,
261                                            FX_UINT nFlag) {
262   if (!IsValid())
263     return TRUE;
264
265   CPDFSDK_PageView* pPageView = GetCurPageView();
266   CommitData(pPageView, nFlag);
267
268   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE))
269     pWnd->KillFocus();
270
271   switch (m_pWidget->GetFieldType()) {
272     case FIELDTYPE_PUSHBUTTON:
273     case FIELDTYPE_CHECKBOX:
274     case FIELDTYPE_RADIOBUTTON:
275       EscapeFiller(pPageView, TRUE);
276       break;
277     default:
278       EscapeFiller(pPageView, FALSE);
279       break;
280   }
281   return TRUE;
282 }
283
284 FX_BOOL CFFL_FormFiller::IsValid() const {
285   return m_bValid;
286 }
287
288 PWL_CREATEPARAM CFFL_FormFiller::GetCreateParam() {
289   ASSERT(m_pApp != NULL);
290
291   PWL_CREATEPARAM cp;
292   cp.pParentWnd = NULL;
293   cp.pProvider = this;
294   cp.rcRectWnd = GetPDFWindowRect();
295
296   FX_DWORD dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
297   FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
298   if (dwFieldFlag & FIELDFLAG_READONLY) {
299     dwCreateFlags |= PWS_READONLY;
300   }
301
302   FX_COLORREF color;
303   if (m_pWidget->GetFillColor(color)) {
304     cp.sBackgroundColor =
305         CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
306   }
307
308   if (m_pWidget->GetBorderColor(color)) {
309     cp.sBorderColor =
310         CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
311   }
312
313   cp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);
314
315   if (m_pWidget->GetTextColor(color)) {
316     cp.sTextColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
317   }
318
319   cp.fFontSize = m_pWidget->GetFontSize();
320   cp.dwBorderWidth = m_pWidget->GetBorderWidth();
321
322   int nBorderStyle = m_pWidget->GetBorderStyle();
323
324   switch (nBorderStyle) {
325     case BBS_SOLID:
326       cp.nBorderStyle = PBS_SOLID;
327       break;
328     case BBS_DASH:
329       cp.nBorderStyle = PBS_DASH;
330       cp.sDash = CPWL_Dash(3, 3, 0);
331       break;
332     case BBS_BEVELED:
333       cp.nBorderStyle = PBS_BEVELED;
334       cp.dwBorderWidth *= 2;
335       break;
336     case BBS_INSET:
337       cp.nBorderStyle = PBS_INSET;
338       cp.dwBorderWidth *= 2;
339       break;
340     case BBS_UNDERLINE:
341       cp.nBorderStyle = PBS_UNDERLINED;
342       break;
343   }
344
345   if (cp.fFontSize <= 0) {
346     dwCreateFlags |= PWS_AUTOFONTSIZE;
347   }
348
349   cp.dwFlags = dwCreateFlags;
350   cp.pSystemHandler = m_pApp->GetSysHandler();
351   return cp;
352 }
353
354 CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView,
355                                         FX_BOOL bNew) {
356   ASSERT(pPageView);
357
358   auto it = m_Maps.find(pPageView);
359   const bool found = it != m_Maps.end();
360   CPWL_Wnd* pWnd = found ? it->second : nullptr;
361   if (!bNew)
362     return pWnd;
363
364   if (found) {
365     CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pWnd->GetAttachedData();
366     if (pPrivateData->nWidgetAge != m_pWidget->GetAppearanceAge()) {
367       return ResetPDFWindow(
368           pPageView, m_pWidget->GetValueAge() == pPrivateData->nValueAge);
369     }
370   } else {
371     PWL_CREATEPARAM cp = GetCreateParam();
372     cp.hAttachedWnd = (FX_HWND)m_pWidget;
373
374     CFFL_PrivateData* pPrivateData = new CFFL_PrivateData;
375     pPrivateData->pWidget = m_pWidget;
376     pPrivateData->pPageView = pPageView;
377     pPrivateData->nWidgetAge = m_pWidget->GetAppearanceAge();
378     pPrivateData->nValueAge = 0;
379
380     cp.pAttachedData = pPrivateData;
381
382     pWnd = NewPDFWindow(cp, pPageView);
383     m_Maps[pPageView] = pWnd;
384   }
385
386   return pWnd;
387 }
388
389 void CFFL_FormFiller::DestroyPDFWindow(CPDFSDK_PageView* pPageView) {
390   auto it = m_Maps.find(pPageView);
391   if (it == m_Maps.end())
392     return;
393
394   CPWL_Wnd* pWnd = it->second;
395   CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
396   pWnd->Destroy();
397   delete pWnd;
398   delete pData;
399
400   m_Maps.erase(it);
401 }
402
403 CPDF_Matrix CFFL_FormFiller::GetWindowMatrix(void* pAttachedData) {
404   if (CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pAttachedData) {
405     if (pPrivateData->pPageView) {
406       CPDF_Matrix mtPageView;
407       pPrivateData->pPageView->GetCurrentMatrix(mtPageView);
408       CPDF_Matrix mt = GetCurMatrix();
409       mt.Concat(mtPageView);
410
411       return mt;
412     }
413   }
414   return CPDF_Matrix(1, 0, 0, 1, 0, 0);
415 }
416
417 CPDF_Matrix CFFL_FormFiller::GetCurMatrix() {
418   CPDF_Matrix mt;
419
420   ASSERT(m_pWidget != NULL);
421
422   CPDF_Rect rcDA;
423   m_pWidget->GetPDFAnnot()->GetRect(rcDA);
424
425   switch (m_pWidget->GetRotate()) {
426     default:
427     case 0:
428       mt = CPDF_Matrix(1, 0, 0, 1, 0, 0);
429       break;
430     case 90:
431       mt = CPDF_Matrix(0, 1, -1, 0, rcDA.right - rcDA.left, 0);
432       break;
433     case 180:
434       mt = CPDF_Matrix(-1, 0, 0, -1, rcDA.right - rcDA.left,
435                        rcDA.top - rcDA.bottom);
436       break;
437     case 270:
438       mt = CPDF_Matrix(0, -1, 1, 0, 0, rcDA.top - rcDA.bottom);
439       break;
440   }
441   mt.e += rcDA.left;
442   mt.f += rcDA.bottom;
443
444   return mt;
445 }
446
447 CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
448   ASSERT(m_pApp != NULL);
449
450   return L"";
451 }
452
453 CPDF_Rect CFFL_FormFiller::GetPDFWindowRect() const {
454   CPDF_Rect rectAnnot;
455   m_pWidget->GetPDFAnnot()->GetRect(rectAnnot);
456
457   FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
458   FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
459   if ((m_pWidget->GetRotate() / 90) & 0x01)
460     return CPDF_Rect(0, 0, fHeight, fWidth);
461
462   return CPDF_Rect(0, 0, fWidth, fHeight);
463 }
464
465 CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView() {
466   CPDF_Page* pPage = m_pAnnot->GetPDFPage();
467   CPDFSDK_Document* pSDKDoc = m_pApp->GetSDKDocument();
468   return pSDKDoc ? pSDKDoc->GetPageView(pPage) : nullptr;
469 }
470
471 CPDF_Rect CFFL_FormFiller::GetFocusBox(CPDFSDK_PageView* pPageView) {
472   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
473     CPDF_Rect rcFocus = FFLtoWnd(pPageView, PWLtoFFL(pWnd->GetFocusRect()));
474     CPDF_Rect rcPage = pPageView->GetPDFPage()->GetPageBBox();
475     if (rcPage.Contains(rcFocus))
476       return rcFocus;
477   }
478   return CPDF_Rect(0, 0, 0, 0);
479 }
480
481 CPDF_Rect CFFL_FormFiller::FFLtoPWL(const CPDF_Rect& rect) {
482   CPDF_Matrix mt;
483   mt.SetReverse(GetCurMatrix());
484
485   CPDF_Rect temp = rect;
486   mt.TransformRect(temp);
487
488   return temp;
489 }
490
491 CPDF_Rect CFFL_FormFiller::PWLtoFFL(const CPDF_Rect& rect) {
492   CPDF_Matrix mt = GetCurMatrix();
493
494   CPDF_Rect temp = rect;
495   mt.TransformRect(temp);
496
497   return temp;
498 }
499
500 CPDF_Point CFFL_FormFiller::FFLtoPWL(const CPDF_Point& point) {
501   CPDF_Matrix mt;
502   mt.SetReverse(GetCurMatrix());
503
504   CPDF_Point pt = point;
505   mt.Transform(pt.x, pt.y);
506
507   return pt;
508 }
509
510 CPDF_Point CFFL_FormFiller::PWLtoFFL(const CPDF_Point& point) {
511   CPDF_Matrix mt = GetCurMatrix();
512
513   CPDF_Point pt = point;
514   mt.Transform(pt.x, pt.y);
515
516   return pt;
517 }
518
519 CPDF_Point CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
520                                      const CPDF_Point& pt) {
521   return FFLtoPWL(pt);
522 }
523
524 CPDF_Rect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
525                                     const CPDF_Rect& rect) {
526   return rect;
527 }
528
529 FX_BOOL CFFL_FormFiller::CommitData(CPDFSDK_PageView* pPageView,
530                                     FX_UINT nFlag) {
531   if (IsDataChanged(pPageView)) {
532     FX_BOOL bRC = TRUE;
533     FX_BOOL bExit = FALSE;
534     CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
535     pIFormFiller->OnKeyStrokeCommit(m_pWidget, pPageView, bRC, bExit, nFlag);
536     if (bExit)
537       return TRUE;
538     if (!bRC) {
539       ResetPDFWindow(pPageView, FALSE);
540       return TRUE;
541     }
542
543     pIFormFiller->OnValidate(m_pWidget, pPageView, bRC, bExit, nFlag);
544     if (bExit)
545       return TRUE;
546     if (!bRC) {
547       ResetPDFWindow(pPageView, FALSE);
548       return TRUE;
549     }
550
551     SaveData(pPageView);
552     pIFormFiller->OnCalculate(m_pWidget, pPageView, bExit, nFlag);
553     if (bExit)
554       return TRUE;
555
556     pIFormFiller->OnFormat(m_pWidget, pPageView, bExit, nFlag);
557   }
558   return TRUE;
559 }
560
561 FX_BOOL CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
562   return FALSE;
563 }
564
565 void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}
566
567 void CFFL_FormFiller::SetChangeMark() {
568   m_pApp->FFI_OnChange();
569 }
570
571 void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView,
572                                     CPDF_AAction::AActionType type,
573                                     PDFSDK_FieldAction& fa) {
574   fa.sValue = m_pWidget->GetValue();
575 }
576
577 void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
578                                     CPDF_AAction::AActionType type,
579                                     const PDFSDK_FieldAction& fa) {}
580
581 FX_BOOL CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type,
582                                              const PDFSDK_FieldAction& faOld,
583                                              const PDFSDK_FieldAction& faNew) {
584   return FALSE;
585 }
586
587 void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}
588
589 void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}
590
591 CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
592                                           FX_BOOL bRestoreValue) {
593   return GetPDFWindow(pPageView, FALSE);
594 }
595
596 void CFFL_FormFiller::TimerProc() {}
597
598 IFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
599   return m_pApp->GetSysHandler();
600 }
601
602 void CFFL_FormFiller::OnKeyStroke(FX_BOOL bKeyDown, FX_DWORD nFlag) {}
603
604 void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView,
605                                    FX_BOOL bDestroyPDFWindow) {
606   m_bValid = FALSE;
607
608   FX_RECT rcRect = GetViewBBox(pPageView, m_pWidget);
609   InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
610
611   if (bDestroyPDFWindow)
612     DestroyPDFWindow(pPageView);
613 }
614
615 void CFFL_FormFiller::InvalidateRect(double left,
616                                      double top,
617                                      double right,
618                                      double bottom) {
619   CPDF_Page* pPage = m_pWidget->GetPDFPage();
620   m_pApp->FFI_Invalidate(pPage, left, top, right, bottom);
621 }
622
623 /* ------------------------- CFFL_Button ------------------------- */
624
625 CFFL_Button::CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget)
626     : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(FALSE), m_bMouseDown(FALSE) {}
627
628 CFFL_Button::~CFFL_Button() {}
629
630 void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView,
631                                CPDFSDK_Annot* pAnnot) {
632   m_bMouseIn = TRUE;
633   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
634   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
635 }
636
637 void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView,
638                               CPDFSDK_Annot* pAnnot) {
639   m_bMouseIn = FALSE;
640
641   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
642   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
643   EndTimer();
644   ASSERT(m_pWidget != NULL);
645 }
646
647 FX_BOOL CFFL_Button::OnLButtonDown(CPDFSDK_PageView* pPageView,
648                                    CPDFSDK_Annot* pAnnot,
649                                    FX_UINT nFlags,
650                                    const CPDF_Point& point) {
651   CPDF_Rect rcAnnot = pAnnot->GetRect();
652   if (!rcAnnot.Contains(point.x, point.y))
653     return FALSE;
654
655   m_bMouseDown = TRUE;
656   m_bValid = TRUE;
657   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
658   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
659   return TRUE;
660 }
661
662 FX_BOOL CFFL_Button::OnLButtonUp(CPDFSDK_PageView* pPageView,
663                                  CPDFSDK_Annot* pAnnot,
664                                  FX_UINT nFlags,
665                                  const CPDF_Point& point) {
666   CPDF_Rect rcAnnot = pAnnot->GetRect();
667   if (!rcAnnot.Contains(point.x, point.y))
668     return FALSE;
669
670   m_bMouseDown = FALSE;
671   m_pWidget->GetPDFPage();
672
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::OnMouseMove(CPDFSDK_PageView* pPageView,
679                                  CPDFSDK_Annot* pAnnot,
680                                  FX_UINT nFlags,
681                                  const CPDF_Point& point) {
682   ASSERT(m_pApp != NULL);
683
684   return TRUE;
685 }
686
687 void CFFL_Button::OnDraw(CPDFSDK_PageView* pPageView,
688                          CPDFSDK_Annot* pAnnot,
689                          CFX_RenderDevice* pDevice,
690                          CPDF_Matrix* pUser2Device,
691                          FX_DWORD dwFlags) {
692   ASSERT(pPageView != NULL);
693   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
694   CPDF_FormControl* pCtrl = pWidget->GetFormControl();
695   CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();
696
697   if (eHM == CPDF_FormControl::Push) {
698     if (m_bMouseDown) {
699       if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
700         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, NULL);
701       else
702         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
703                                 NULL);
704     } else if (m_bMouseIn) {
705       if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
706         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover,
707                                 NULL);
708       else
709         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
710                                 NULL);
711     } else {
712       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
713     }
714   } else
715     pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
716 }
717
718 void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView* pPageView,
719                                  CPDFSDK_Annot* pAnnot,
720                                  CFX_RenderDevice* pDevice,
721                                  CPDF_Matrix* pUser2Device,
722                                  FX_DWORD dwFlags) {
723   OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
724 }