Use stdint.h types throughout PDFium.
[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
16 #define FFL_DEFAULTLISTBOXFONTSIZE              12.0f
17
18
19 /* ------------------------------- CFFL_ListBox ------------------------------- */
20
21 CFFL_ListBox::CFFL_ListBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
22         CFFL_FormFiller(pApp, pWidget),
23         m_pFontMap(NULL)
24 {
25 }
26
27 CFFL_ListBox::~CFFL_ListBox()
28 {
29         if (m_pFontMap)
30         {
31                 delete m_pFontMap;
32                 m_pFontMap = NULL;
33         }
34 }
35
36 PWL_CREATEPARAM CFFL_ListBox::GetCreateParam()
37 {
38         PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
39
40         ASSERT(m_pWidget != NULL);
41         FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
42                 
43         if (dwFieldFlag & FIELDFLAG_MULTISELECT)
44         {               
45                 cp.dwFlags |= PLBS_MULTIPLESEL;
46         }
47
48         if (dwFieldFlag & FIELDFLAG_COMMITONSELCHANGE)
49         {
50                 //cp.dwFlags |= PLBS_COMMITSELECTEDVALUE;
51         }
52
53         cp.dwFlags |= PWS_VSCROLL;
54
55         if (cp.dwFlags & PWS_AUTOFONTSIZE)
56                 cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE;
57
58         if (!m_pFontMap)
59         {
60                 ASSERT(this->m_pApp != NULL);
61                 m_pFontMap = new CBA_FontMap(m_pWidget,m_pApp->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pApp));
62                 m_pFontMap->Initial();
63         }
64         cp.pFontMap = m_pFontMap;
65
66         return cp;
67 }
68
69 CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
70 {
71         CPWL_ListBox* pWnd = new CPWL_ListBox();
72         pWnd->AttachFFLData(this);
73         pWnd->Create(cp);
74
75         ASSERT(m_pApp != NULL);
76         CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
77         pWnd->SetFillerNotify(pIFormFiller);
78
79         for (int32_t i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
80                 pWnd->AddString(m_pWidget->GetOptionLabel(i).c_str());
81
82         if (pWnd->HasFlag(PLBS_MULTIPLESEL))
83         {
84                 m_OriginSelections.RemoveAll();
85                 
86                 FX_BOOL bSetCaret = FALSE;
87                 for (int32_t i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
88                 {
89                         if (m_pWidget->IsOptionSelected(i))
90                         {
91                                 if (!bSetCaret)
92                                 {
93                                         pWnd->SetCaret(i);
94                                         bSetCaret = TRUE;
95                                 }
96                                 pWnd->Select(i);
97                                 m_OriginSelections.SetAt(i, NULL);
98                         }
99                 }
100         }
101         else
102         {
103                 for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
104                 {
105                         if (m_pWidget->IsOptionSelected(i))
106                         {
107                                 pWnd->Select(i);
108                                 break;
109                         }
110                 }
111         }
112         
113         pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
114         
115         return pWnd;
116 }
117
118
119 FX_BOOL CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
120 {
121         return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
122 }
123
124 FX_BOOL CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView)
125 {
126         ASSERT(m_pWidget != NULL);
127
128         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
129         {
130                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
131                 {
132                         int nSelCount = 0;
133                         for (int32_t i=0,sz=pListBox->GetCount(); i<sz; i++)
134                         {
135                                 if (pListBox->IsItemSelected(i))
136                                 {
137                                         void* p = NULL;
138                                         if (!m_OriginSelections.Lookup(i, p))
139                                                 return TRUE;
140
141                                         nSelCount++;
142                                 }
143                         }
144
145                         return nSelCount != m_OriginSelections.GetCount();
146                 }
147                 else
148                 {
149                         return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
150                 }
151         }
152         
153         return FALSE;
154 }
155
156 void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView)
157 {
158         ASSERT(m_pWidget != NULL);
159
160         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
161         {
162                 CFX_IntArray aOldSelect, aNewSelect;
163
164                 {
165                         for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
166                         {
167                                 if (m_pWidget->IsOptionSelected(i))
168                                 {
169                                         aOldSelect.Add(i);
170                                 }
171                         }
172                 }
173
174                 
175                 int32_t nNewTopIndex = pListBox->GetTopVisibleIndex();
176
177                 m_pWidget->ClearSelection(FALSE);       
178
179                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
180                 {
181                         for (int32_t i=0,sz=pListBox->GetCount(); i<sz; i++)
182                         {
183                                 if (pListBox->IsItemSelected(i))
184                                 {
185                                         m_pWidget->SetOptionSelection(i, TRUE, FALSE);
186                                         aNewSelect.Add(i);
187                                 }
188                         }
189                 }
190                 else
191                 {
192                         m_pWidget->SetOptionSelection(pListBox->GetCurSel(), TRUE, FALSE);
193                         aNewSelect.Add(pListBox->GetCurSel());
194                 }
195
196                 m_pWidget->SetTopVisibleIndex(nNewTopIndex);
197                 m_pWidget->ResetFieldAppearance(TRUE);
198                 m_pWidget->UpdateField();
199                 SetChangeMark();
200         }
201 }
202
203 void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
204                                                 PDFSDK_FieldAction& fa)
205 {
206         switch (type)
207         {
208         case CPDF_AAction::Validate:
209                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
210                 {
211                         fa.sValue = L"";
212                 }
213                 else
214                 {
215                         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
216                         {
217                                 ASSERT(m_pWidget != NULL);
218                                 int32_t nCurSel = pListBox->GetCurSel();
219                                 if (nCurSel >= 0)
220                                         fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
221                         }
222                 }
223                 break;
224         case CPDF_AAction::LoseFocus:
225         case CPDF_AAction::GetFocus:
226                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
227                 {
228                         fa.sValue = L"";
229                 }
230                 else
231                 {
232                         ASSERT(m_pWidget != NULL);
233                         int32_t nCurSel = m_pWidget->GetSelectedIndex(0);
234                         if (nCurSel >= 0)
235                                 fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
236                 }
237                 break;
238         default:
239                 break;
240         }
241 }
242
243
244 void CFFL_ListBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
245                                                                 const PDFSDK_FieldAction& fa)
246 {
247 }
248
249 void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView)
250 {
251         ASSERT(pPageView != NULL);
252
253         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
254         {
255                 for (int32_t i=0,sz=pListBox->GetCount(); i<sz; i++)
256                 {
257                         if (pListBox->IsItemSelected(i))
258                         {
259                                 m_State.Add(i);
260                         }
261                 }
262         }
263 }
264
265 void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView)
266 {
267         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
268         {
269                 for (int i=0,sz=m_State.GetSize(); i<sz; i++)
270                         pListBox->Select(m_State[i]);
271         }
272 }
273
274 CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
275 {
276         if (bRestoreValue)
277                 SaveState(pPageView);
278         
279         DestroyPDFWindow(pPageView);
280         
281         CPWL_Wnd* pRet = NULL;
282         
283         if (bRestoreValue)
284         {
285                 RestoreState(pPageView);
286                 pRet = this->GetPDFWindow(pPageView, FALSE);
287         }
288         else
289                 pRet = this->GetPDFWindow(pPageView, TRUE);
290         
291         m_pWidget->UpdateField();
292         
293         return pRet;
294 }
295
296 void CFFL_ListBox::OnKeyStroke(FX_BOOL bKeyDown, FX_DWORD nFlag)
297 {
298         ASSERT(m_pWidget != NULL);
299
300         int nFlags = m_pWidget->GetFieldFlags();
301         
302         if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
303         {
304                 if (m_bValid)
305                 {
306                         CPDFSDK_PageView* pPageView = this->GetCurPageView();
307                         ASSERT(pPageView != NULL);
308
309                         if (CommitData(pPageView, nFlag))
310                         {
311                                 DestroyPDFWindow(pPageView);
312                                 m_bValid = FALSE;
313                         }
314                 }
315         }
316 }
317