Clean up CPDF_AnnotList.
[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_CBA_Fontmap.h"
9
10 #define GetRed(rgb) ((uint8_t)(rgb))
11 #define GetGreen(rgb) ((uint8_t)(((FX_WORD)(rgb)) >> 8))
12 #define GetBlue(rgb) ((uint8_t)((rgb) >> 16))
13
14 #define FFL_HINT_ELAPSE 800
15
16 /* ------------------------- CFFL_FormFiller ------------------------- */
17
18 CFFL_FormFiller::CFFL_FormFiller(CPDFDoc_Environment* pApp,
19                                  CPDFSDK_Annot* pAnnot)
20     : m_pApp(pApp), m_pAnnot(pAnnot), m_bValid(FALSE), m_ptOldPos(0, 0) {
21   m_pWidget = (CPDFSDK_Widget*)pAnnot;
22 }
23
24 CFFL_FormFiller::~CFFL_FormFiller() {
25   for (auto& it : m_Maps) {
26     CPWL_Wnd* pWnd = it.second;
27     CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
28     pWnd->Destroy();
29     delete pWnd;
30     delete pData;
31   }
32   m_Maps.clear();
33 }
34
35 void CFFL_FormFiller::SetWindowRect(CPDFSDK_PageView* pPageView,
36                                     const CPDF_Rect& rcWindow) {
37   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
38     pWnd->Move(CPDF_Rect(rcWindow), TRUE, FALSE);
39   }
40 }
41
42 CPDF_Rect CFFL_FormFiller::GetWindowRect(CPDFSDK_PageView* pPageView) {
43   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
44     return pWnd->GetWindowRect();
45   }
46
47   return CPDF_Rect(0, 0, 0, 0);
48 }
49
50 FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
51                                      CPDFSDK_Annot* pAnnot) {
52   ASSERT(pPageView != NULL);
53   ASSERT(pAnnot != NULL);
54
55   CPDF_Rect rcAnnot = m_pWidget->GetRect();
56
57   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
58     CPDF_Rect rcWindow = pWnd->GetWindowRect();
59     rcAnnot = PWLtoFFL(rcWindow);
60   }
61
62   CPDF_Rect rcWin = rcAnnot;
63
64   CPDF_Rect rcFocus = GetFocusBox(pPageView);
65   if (!rcFocus.IsEmpty())
66     rcWin.Union(rcFocus);
67
68   CPDF_Rect rect = CPWL_Utils::InflateRect(rcWin, 1);
69
70   return rect.GetOutterRect();
71 }
72
73 void CFFL_FormFiller::OnDraw(CPDFSDK_PageView* pPageView,
74                              CPDFSDK_Annot* pAnnot,
75                              CFX_RenderDevice* pDevice,
76                              CPDF_Matrix* pUser2Device,
77                              FX_DWORD dwFlags) {
78   ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
79
80   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
81     CPDF_Matrix mt = GetCurMatrix();
82     mt.Concat(*pUser2Device);
83     pWnd->DrawAppearance(pDevice, &mt);
84   } else {
85     CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
86     if (CFFL_IFormFiller::IsVisible(pWidget))
87       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
88   }
89 }
90
91 void CFFL_FormFiller::OnDrawDeactive(CPDFSDK_PageView* pPageView,
92                                      CPDFSDK_Annot* pAnnot,
93                                      CFX_RenderDevice* pDevice,
94                                      CPDF_Matrix* pUser2Device,
95                                      FX_DWORD dwFlags) {
96   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
97   pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
98 }
99
100 void CFFL_FormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {}
101
102 void CFFL_FormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {}
103
104 void CFFL_FormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {}
105
106 void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
107                                    CPDFSDK_Annot* pAnnot) {}
108
109 void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
110                                   CPDFSDK_Annot* pAnnot) {
111   EndTimer();
112   ASSERT(m_pWidget != NULL);
113 }
114
115 FX_BOOL CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
116                                        CPDFSDK_Annot* pAnnot,
117                                        FX_UINT nFlags,
118                                        const CPDF_Point& point) {
119   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
120     m_bValid = TRUE;
121     FX_RECT rect = GetViewBBox(pPageView, pAnnot);
122     InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
123
124     if (!rect.Contains((int)point.x, (int)point.y))
125       return FALSE;
126
127     return pWnd->OnLButtonDown(WndtoPWL(pPageView, point), nFlags);
128   }
129
130   return FALSE;
131 }
132
133 FX_BOOL CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
134                                      CPDFSDK_Annot* pAnnot,
135                                      FX_UINT nFlags,
136                                      const CPDF_Point& point) {
137   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
138     FX_RECT rcFFL = GetViewBBox(pPageView, pAnnot);
139     InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom);
140     pWnd->OnLButtonUp(WndtoPWL(pPageView, point), nFlags);
141     return TRUE;
142   }
143
144   return FALSE;
145 }
146
147 FX_BOOL CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
148                                          CPDFSDK_Annot* pAnnot,
149                                          FX_UINT nFlags,
150                                          const CPDF_Point& point) {
151   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
152     pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point), nFlags);
153     return TRUE;
154   }
155
156   return FALSE;
157 }
158
159 FX_BOOL CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
160                                      CPDFSDK_Annot* pAnnot,
161                                      FX_UINT nFlags,
162                                      const CPDF_Point& point) {
163   if ((m_ptOldPos.x != point.x) || (m_ptOldPos.y != point.y)) {
164     m_ptOldPos = point;
165   }
166
167   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
168     pWnd->OnMouseMove(WndtoPWL(pPageView, point), nFlags);
169     return TRUE;
170   }
171
172   return FALSE;
173 }
174
175 FX_BOOL CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
176                                       CPDFSDK_Annot* pAnnot,
177                                       FX_UINT nFlags,
178                                       short zDelta,
179                                       const CPDF_Point& point) {
180   if (!IsValid())
181     return FALSE;
182
183   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
184     return pWnd->OnMouseWheel(zDelta, WndtoPWL(pPageView, point), nFlags);
185   }
186
187   return FALSE;
188 }
189
190 FX_BOOL CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
191                                        CPDFSDK_Annot* pAnnot,
192                                        FX_UINT nFlags,
193                                        const CPDF_Point& point) {
194   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
195     pWnd->OnRButtonDown(WndtoPWL(pPageView, point), nFlags);
196     return TRUE;
197   }
198
199   return FALSE;
200 }
201
202 FX_BOOL CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
203                                      CPDFSDK_Annot* pAnnot,
204                                      FX_UINT nFlags,
205                                      const CPDF_Point& point) {
206   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
207     pWnd->OnRButtonUp(WndtoPWL(pPageView, point), nFlags);
208     return TRUE;
209   }
210
211   return FALSE;
212 }
213
214 FX_BOOL CFFL_FormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
215                                    FX_UINT nKeyCode,
216                                    FX_UINT nFlags) {
217   if (IsValid()) {
218     CPDFSDK_PageView* pPageView = GetCurPageView();
219     ASSERT(pPageView != NULL);
220
221     if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
222       return pWnd->OnKeyDown(nKeyCode, nFlags);
223     }
224   }
225
226   return FALSE;
227 }
228
229 FX_BOOL CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot,
230                                 FX_UINT nChar,
231                                 FX_UINT nFlags) {
232   if (IsValid()) {
233     CPDFSDK_PageView* pPageView = GetCurPageView();
234     ASSERT(pPageView != NULL);
235
236     if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
237       return pWnd->OnChar(nChar, nFlags);
238     }
239   }
240
241   return FALSE;
242 }
243
244 void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
245   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
246   CPDF_Page* pPage = pWidget->GetPDFPage();
247   CPDFSDK_Document* pDoc = m_pApp->GetSDKDocument();
248   CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage);
249   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
250     pWnd->SetFocus();
251
252   m_bValid = TRUE;
253   FX_RECT rcRect = GetViewBBox(pPageView, pAnnot);
254   InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
255 }
256
257 void CFFL_FormFiller::KillFocusForAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
258   if (!IsValid())
259     return;
260
261   CPDFSDK_PageView* pPageView = GetCurPageView();
262   if (!pPageView)
263     return;
264
265   CommitData(pPageView, nFlag);
266
267   if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE))
268     pWnd->KillFocus();
269
270   FX_BOOL bDestroyPDFWindow;
271   switch (m_pWidget->GetFieldType()) {
272     case FIELDTYPE_PUSHBUTTON:
273     case FIELDTYPE_CHECKBOX:
274     case FIELDTYPE_RADIOBUTTON:
275       bDestroyPDFWindow = TRUE;
276     default:
277       bDestroyPDFWindow = FALSE;
278   }
279   EscapeFiller(pPageView, bDestroyPDFWindow);
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::EscapeFiller(CPDFSDK_PageView* pPageView,
601                                    FX_BOOL bDestroyPDFWindow) {
602   m_bValid = FALSE;
603
604   FX_RECT rcRect = GetViewBBox(pPageView, m_pWidget);
605   InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
606
607   if (bDestroyPDFWindow)
608     DestroyPDFWindow(pPageView);
609 }
610
611 void CFFL_FormFiller::InvalidateRect(double left,
612                                      double top,
613                                      double right,
614                                      double bottom) {
615   CPDF_Page* pPage = m_pWidget->GetPDFPage();
616   m_pApp->FFI_Invalidate(pPage, left, top, right, bottom);
617 }
618
619 /* ------------------------- CFFL_Button ------------------------- */
620
621 CFFL_Button::CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget)
622     : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(FALSE), m_bMouseDown(FALSE) {}
623
624 CFFL_Button::~CFFL_Button() {}
625
626 void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView,
627                                CPDFSDK_Annot* pAnnot) {
628   m_bMouseIn = TRUE;
629   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
630   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
631 }
632
633 void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView,
634                               CPDFSDK_Annot* pAnnot) {
635   m_bMouseIn = FALSE;
636
637   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
638   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
639   EndTimer();
640   ASSERT(m_pWidget != NULL);
641 }
642
643 FX_BOOL CFFL_Button::OnLButtonDown(CPDFSDK_PageView* pPageView,
644                                    CPDFSDK_Annot* pAnnot,
645                                    FX_UINT nFlags,
646                                    const CPDF_Point& point) {
647   CPDF_Rect rcAnnot = pAnnot->GetRect();
648   if (!rcAnnot.Contains(point.x, point.y))
649     return FALSE;
650
651   m_bMouseDown = TRUE;
652   m_bValid = TRUE;
653   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
654   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
655   return TRUE;
656 }
657
658 FX_BOOL CFFL_Button::OnLButtonUp(CPDFSDK_PageView* pPageView,
659                                  CPDFSDK_Annot* pAnnot,
660                                  FX_UINT nFlags,
661                                  const CPDF_Point& point) {
662   CPDF_Rect rcAnnot = pAnnot->GetRect();
663   if (!rcAnnot.Contains(point.x, point.y))
664     return FALSE;
665
666   m_bMouseDown = FALSE;
667   m_pWidget->GetPDFPage();
668
669   FX_RECT rect = GetViewBBox(pPageView, pAnnot);
670   InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
671   return TRUE;
672 }
673
674 FX_BOOL CFFL_Button::OnMouseMove(CPDFSDK_PageView* pPageView,
675                                  CPDFSDK_Annot* pAnnot,
676                                  FX_UINT nFlags,
677                                  const CPDF_Point& point) {
678   ASSERT(m_pApp != NULL);
679
680   return TRUE;
681 }
682
683 void CFFL_Button::OnDraw(CPDFSDK_PageView* pPageView,
684                          CPDFSDK_Annot* pAnnot,
685                          CFX_RenderDevice* pDevice,
686                          CPDF_Matrix* pUser2Device,
687                          FX_DWORD dwFlags) {
688   ASSERT(pPageView != NULL);
689   CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
690   CPDF_FormControl* pCtrl = pWidget->GetFormControl();
691   CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();
692
693   if (eHM == CPDF_FormControl::Push) {
694     if (m_bMouseDown) {
695       if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
696         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, NULL);
697       else
698         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
699                                 NULL);
700     } else if (m_bMouseIn) {
701       if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
702         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover,
703                                 NULL);
704       else
705         pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
706                                 NULL);
707     } else {
708       pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
709     }
710   } else
711     pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
712 }
713
714 void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView* pPageView,
715                                  CPDFSDK_Annot* pAnnot,
716                                  CFX_RenderDevice* pDevice,
717                                  CPDF_Matrix* pUser2Device,
718                                  FX_DWORD dwFlags) {
719   OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
720 }