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/formfiller/cffl_radiobutton.h"
8
9 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
10 #include "fpdfsdk/cpdfsdk_widget.h"
11 #include "fpdfsdk/formfiller/cffl_formfiller.h"
12 #include "fpdfsdk/pwl/cpwl_special_button.h"
13 #include "public/fpdf_fwlevent.h"
14
CFFL_RadioButton(CPDFSDK_FormFillEnvironment * pApp,CPDFSDK_Widget * pWidget)15 CFFL_RadioButton::CFFL_RadioButton(CPDFSDK_FormFillEnvironment* pApp,
16 CPDFSDK_Widget* pWidget)
17 : CFFL_Button(pApp, pWidget) {}
18
~CFFL_RadioButton()19 CFFL_RadioButton::~CFFL_RadioButton() {}
20
NewPDFWindow(const CPWL_Wnd::CreateParams & cp)21 CPWL_Wnd* CFFL_RadioButton::NewPDFWindow(const CPWL_Wnd::CreateParams& cp) {
22 auto* pWnd = new CPWL_RadioButton();
23 pWnd->Create(cp);
24 pWnd->SetCheck(m_pWidget->IsChecked());
25 return pWnd;
26 }
27
OnKeyDown(CPDFSDK_Annot * pAnnot,uint32_t nKeyCode,uint32_t nFlags)28 bool CFFL_RadioButton::OnKeyDown(CPDFSDK_Annot* pAnnot,
29 uint32_t nKeyCode,
30 uint32_t nFlags) {
31 switch (nKeyCode) {
32 case FWL_VKEY_Return:
33 case FWL_VKEY_Space:
34 return true;
35 default:
36 return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
37 }
38 }
39
OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)40 bool CFFL_RadioButton::OnChar(CPDFSDK_Annot* pAnnot,
41 uint32_t nChar,
42 uint32_t nFlags) {
43 switch (nChar) {
44 case FWL_VKEY_Return:
45 case FWL_VKEY_Space: {
46 CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
47 ASSERT(pPageView);
48
49 CPDFSDK_Annot::ObservedPtr pObserved(m_pWidget.Get());
50 if (m_pFormFillEnv->GetInteractiveFormFiller()->OnButtonUp(
51 &pObserved, pPageView, nFlags) ||
52 !pObserved) {
53 return true;
54 }
55
56 CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
57 CPWL_RadioButton* pWnd = GetRadioButton(pPageView, true);
58 if (pWnd)
59 pWnd->SetCheck(true);
60 return CommitData(pPageView, nFlags);
61 }
62 default:
63 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
64 }
65 }
66
OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,uint32_t nFlags,const CFX_PointF & point)67 bool CFFL_RadioButton::OnLButtonUp(CPDFSDK_PageView* pPageView,
68 CPDFSDK_Annot* pAnnot,
69 uint32_t nFlags,
70 const CFX_PointF& point) {
71 CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
72
73 if (!IsValid())
74 return true;
75
76 CPWL_RadioButton* pWnd = GetRadioButton(pPageView, true);
77 if (pWnd)
78 pWnd->SetCheck(true);
79
80 return CommitData(pPageView, nFlags);
81 }
82
IsDataChanged(CPDFSDK_PageView * pPageView)83 bool CFFL_RadioButton::IsDataChanged(CPDFSDK_PageView* pPageView) {
84 CPWL_RadioButton* pWnd = GetRadioButton(pPageView, false);
85 return pWnd && pWnd->IsChecked() != m_pWidget->IsChecked();
86 }
87
SaveData(CPDFSDK_PageView * pPageView)88 void CFFL_RadioButton::SaveData(CPDFSDK_PageView* pPageView) {
89 CPWL_RadioButton* pWnd = GetRadioButton(pPageView, false);
90 if (!pWnd)
91 return;
92
93 bool bNewChecked = pWnd->IsChecked();
94
95 if (bNewChecked) {
96 CPDF_FormField* pField = m_pWidget->GetFormField();
97 for (int32_t i = 0, sz = pField->CountControls(); i < sz; i++) {
98 if (CPDF_FormControl* pCtrl = pField->GetControl(i)) {
99 if (pCtrl->IsChecked()) {
100 break;
101 }
102 }
103 }
104 }
105 CPDFSDK_Widget::ObservedPtr observed_widget(m_pWidget.Get());
106 CFFL_RadioButton::ObservedPtr observed_this(this);
107
108 m_pWidget->SetCheck(bNewChecked, false);
109 if (!observed_widget)
110 return;
111 m_pWidget->UpdateField();
112 if (!observed_widget || !observed_this)
113 return;
114 SetChangeMark();
115 }
116
GetRadioButton(CPDFSDK_PageView * pPageView,bool bNew)117 CPWL_RadioButton* CFFL_RadioButton::GetRadioButton(CPDFSDK_PageView* pPageView,
118 bool bNew) {
119 return static_cast<CPWL_RadioButton*>(GetPDFWindow(pPageView, bNew));
120 }
121