Rename Init methods to more accurately describe purpose
[pdfium.git] / fpdfsdk / src / formfiller / FFL_ListBox.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/FormFiller.h"
8 #include "../../include/formfiller/FFL_FormFiller.h"
9 #include "../../include/formfiller/FFL_ListBox.h"
10 //#include "../../include/formfiller/FFL_Module.h"
11 #include "../../include/formfiller/FFL_IFormFiller.h"
12 //#include "../../include/formfiller/FFL_Undo.h"
13 #include "../../include/formfiller/FFL_CBA_Fontmap.h"
14
15 #define FFL_DEFAULTLISTBOXFONTSIZE 12.0f
16
17 /* ------------------------------- CFFL_ListBox -------------------------------
18  */
19
20 CFFL_ListBox::CFFL_ListBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget)
21     : CFFL_FormFiller(pApp, pWidget), m_pFontMap(NULL) {}
22
23 CFFL_ListBox::~CFFL_ListBox() {
24   delete m_pFontMap;
25 }
26
27 PWL_CREATEPARAM CFFL_ListBox::GetCreateParam() {
28   PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
29
30   ASSERT(m_pWidget != NULL);
31   FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
32
33   if (dwFieldFlag & FIELDFLAG_MULTISELECT) {
34     cp.dwFlags |= PLBS_MULTIPLESEL;
35   }
36
37   cp.dwFlags |= PWS_VSCROLL;
38
39   if (cp.dwFlags & PWS_AUTOFONTSIZE)
40     cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE;
41
42   if (!m_pFontMap) {
43     m_pFontMap = new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler());
44     m_pFontMap->Initial();
45   }
46   cp.pFontMap = m_pFontMap;
47
48   return cp;
49 }
50
51 CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp,
52                                      CPDFSDK_PageView* pPageView) {
53   CPWL_ListBox* pWnd = new CPWL_ListBox();
54   pWnd->AttachFFLData(this);
55   pWnd->Create(cp);
56
57   ASSERT(m_pApp != NULL);
58   CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
59   pWnd->SetFillerNotify(pIFormFiller);
60
61   for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++)
62     pWnd->AddString(m_pWidget->GetOptionLabel(i).c_str());
63
64   if (pWnd->HasFlag(PLBS_MULTIPLESEL)) {
65     m_OriginSelections.clear();
66
67     FX_BOOL bSetCaret = FALSE;
68     for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
69       if (m_pWidget->IsOptionSelected(i)) {
70         if (!bSetCaret) {
71           pWnd->SetCaret(i);
72           bSetCaret = TRUE;
73         }
74         pWnd->Select(i);
75         m_OriginSelections.insert(i);
76       }
77     }
78   } else {
79     for (int i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
80       if (m_pWidget->IsOptionSelected(i)) {
81         pWnd->Select(i);
82         break;
83       }
84     }
85   }
86
87   pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
88
89   return pWnd;
90 }
91
92 FX_BOOL CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot,
93                              FX_UINT nChar,
94                              FX_UINT nFlags) {
95   return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
96 }
97
98 FX_BOOL CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
99   CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE);
100   if (!pListBox)
101     return FALSE;
102
103   if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
104     size_t nSelCount = 0;
105     for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; ++i) {
106       if (pListBox->IsItemSelected(i)) {
107         if (m_OriginSelections.count(i) == 0)
108           return TRUE;
109
110         ++nSelCount;
111       }
112     }
113
114     return nSelCount != m_OriginSelections.size();
115   }
116   return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
117 }
118
119 void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView) {
120   ASSERT(m_pWidget != NULL);
121
122   if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE)) {
123     CFX_IntArray aOldSelect, aNewSelect;
124
125     {
126       for (int i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
127         if (m_pWidget->IsOptionSelected(i)) {
128           aOldSelect.Add(i);
129         }
130       }
131     }
132
133     int32_t nNewTopIndex = pListBox->GetTopVisibleIndex();
134
135     m_pWidget->ClearSelection(FALSE);
136
137     if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
138       for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
139         if (pListBox->IsItemSelected(i)) {
140           m_pWidget->SetOptionSelection(i, TRUE, FALSE);
141           aNewSelect.Add(i);
142         }
143       }
144     } else {
145       m_pWidget->SetOptionSelection(pListBox->GetCurSel(), TRUE, FALSE);
146       aNewSelect.Add(pListBox->GetCurSel());
147     }
148
149     m_pWidget->SetTopVisibleIndex(nNewTopIndex);
150     m_pWidget->ResetFieldAppearance(TRUE);
151     m_pWidget->UpdateField();
152     SetChangeMark();
153   }
154 }
155
156 void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView,
157                                  CPDF_AAction::AActionType type,
158                                  PDFSDK_FieldAction& fa) {
159   switch (type) {
160     case CPDF_AAction::Validate:
161       if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
162         fa.sValue = L"";
163       } else {
164         if (CPWL_ListBox* pListBox =
165                 (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE)) {
166           ASSERT(m_pWidget != NULL);
167           int32_t nCurSel = pListBox->GetCurSel();
168           if (nCurSel >= 0)
169             fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
170         }
171       }
172       break;
173     case CPDF_AAction::LoseFocus:
174     case CPDF_AAction::GetFocus:
175       if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
176         fa.sValue = L"";
177       } else {
178         ASSERT(m_pWidget != NULL);
179         int32_t nCurSel = m_pWidget->GetSelectedIndex(0);
180         if (nCurSel >= 0)
181           fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
182       }
183       break;
184     default:
185       break;
186   }
187 }
188
189 void CFFL_ListBox::SetActionData(CPDFSDK_PageView* pPageView,
190                                  CPDF_AAction::AActionType type,
191                                  const PDFSDK_FieldAction& fa) {}
192
193 void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView) {
194   ASSERT(pPageView != NULL);
195
196   if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE)) {
197     for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
198       if (pListBox->IsItemSelected(i)) {
199         m_State.Add(i);
200       }
201     }
202   }
203 }
204
205 void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView) {
206   if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE)) {
207     for (int i = 0, sz = m_State.GetSize(); i < sz; i++)
208       pListBox->Select(m_State[i]);
209   }
210 }
211
212 CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView,
213                                        FX_BOOL bRestoreValue) {
214   if (bRestoreValue)
215     SaveState(pPageView);
216
217   DestroyPDFWindow(pPageView);
218
219   CPWL_Wnd* pRet = NULL;
220
221   if (bRestoreValue) {
222     RestoreState(pPageView);
223     pRet = GetPDFWindow(pPageView, FALSE);
224   } else
225     pRet = GetPDFWindow(pPageView, TRUE);
226
227   m_pWidget->UpdateField();
228
229   return pRet;
230 }
231
232 void CFFL_ListBox::OnKeyStroke(FX_BOOL bKeyDown, FX_DWORD nFlag) {
233   ASSERT(m_pWidget != NULL);
234
235   int nFlags = m_pWidget->GetFieldFlags();
236
237   if (nFlags & FIELDFLAG_COMMITONSELCHANGE) {
238     if (m_bValid) {
239       CPDFSDK_PageView* pPageView = GetCurPageView();
240       ASSERT(pPageView != NULL);
241
242       if (CommitData(pPageView, nFlag)) {
243         DestroyPDFWindow(pPageView);
244         m_bValid = FALSE;
245       }
246     }
247   }
248 }