Convert all line endings to LF.
[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         ASSERT(m_pWidget != NULL);
80         
81         for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
82                 pWnd->AddString(m_pWidget->GetOptionLabel(i));
83         
84         if (pWnd->HasFlag(PLBS_MULTIPLESEL))
85         {
86                 m_OriginSelections.RemoveAll();
87                 
88                 FX_BOOL bSetCaret = FALSE;
89                 for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
90                 {
91                         if (m_pWidget->IsOptionSelected(i))
92                         {
93                                 if (!bSetCaret)
94                                 {
95                                         pWnd->SetCaret(i);
96                                         bSetCaret = TRUE;
97                                 }
98                                 pWnd->Select(i);
99                                 m_OriginSelections.SetAt(i, NULL);
100                         }
101                 }
102         }
103         else
104         {
105                 for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
106                 {
107                         if (m_pWidget->IsOptionSelected(i))
108                         {
109                                 pWnd->Select(i);
110                                 break;
111                         }
112                 }
113         }
114         
115         pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
116         
117         return pWnd;
118 }
119
120
121 FX_BOOL CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
122 {
123         return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
124 }
125
126 FX_BOOL CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView)
127 {
128         ASSERT(m_pWidget != NULL);
129
130         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
131         {
132                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
133                 {
134                         int nSelCount = 0;
135                         for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
136                         {
137                                 if (pListBox->IsItemSelected(i))
138                                 {
139                                         void* p = NULL;
140                                         if (!m_OriginSelections.Lookup(i, p))
141                                                 return TRUE;
142
143                                         nSelCount++;
144                                 }
145                         }
146
147                         return nSelCount != m_OriginSelections.GetCount();
148                 }
149                 else
150                 {
151                         return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
152                 }
153         }
154         
155         return FALSE;
156 }
157
158 void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView)
159 {
160         ASSERT(m_pWidget != NULL);
161
162         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
163         {
164                 CFX_IntArray aOldSelect, aNewSelect;
165
166                 {
167                         for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
168                         {
169                                 if (m_pWidget->IsOptionSelected(i))
170                                 {
171                                         aOldSelect.Add(i);
172                                 }
173                         }
174                 }
175
176                 
177                 FX_INT32 nNewTopIndex = pListBox->GetTopVisibleIndex();
178
179                 m_pWidget->ClearSelection(FALSE);       
180
181                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
182                 {
183                         for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
184                         {
185                                 if (pListBox->IsItemSelected(i))
186                                 {
187                                         m_pWidget->SetOptionSelection(i, TRUE, FALSE);
188                                         aNewSelect.Add(i);
189                                 }
190                         }
191                 }
192                 else
193                 {
194                         m_pWidget->SetOptionSelection(pListBox->GetCurSel(), TRUE, FALSE);
195                         aNewSelect.Add(pListBox->GetCurSel());
196                 }
197
198                 m_pWidget->SetTopVisibleIndex(nNewTopIndex);
199                 m_pWidget->ResetFieldAppearance(TRUE);
200                 m_pWidget->UpdateField();
201                 SetChangeMark();
202         }
203 }
204
205 void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
206                                                 PDFSDK_FieldAction& fa)
207 {
208         switch (type)
209         {
210         case CPDF_AAction::Validate:
211                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
212                 {
213                         fa.sValue = L"";
214                 }
215                 else
216                 {
217                         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
218                         {
219                                 ASSERT(m_pWidget != NULL);
220                                 FX_INT32 nCurSel = pListBox->GetCurSel();
221                                 if (nCurSel >= 0)
222                                         fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
223                         }
224                 }
225                 break;
226         case CPDF_AAction::LoseFocus:
227         case CPDF_AAction::GetFocus:
228                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
229                 {
230                         fa.sValue = L"";
231                 }
232                 else
233                 {
234                         ASSERT(m_pWidget != NULL);
235                         FX_INT32 nCurSel = m_pWidget->GetSelectedIndex(0);
236                         if (nCurSel >= 0)
237                                 fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
238                 }
239                 break;
240         default:
241                 break;
242         }
243 }
244
245
246 void CFFL_ListBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
247                                                                 const PDFSDK_FieldAction& fa)
248 {
249 }
250
251 void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView)
252 {
253         ASSERT(pPageView != NULL);
254
255         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
256         {
257                 for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
258                 {
259                         if (pListBox->IsItemSelected(i))
260                         {
261                                 m_State.Add(i);
262                         }
263                 }
264         }
265 }
266
267 void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView)
268 {
269         if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
270         {
271                 for (int i=0,sz=m_State.GetSize(); i<sz; i++)
272                         pListBox->Select(m_State[i]);
273         }
274 }
275
276 CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
277 {
278         if (bRestoreValue)
279                 SaveState(pPageView);
280         
281         DestroyPDFWindow(pPageView);
282         
283         CPWL_Wnd* pRet = NULL;
284         
285         if (bRestoreValue)
286         {
287                 RestoreState(pPageView);
288                 pRet = this->GetPDFWindow(pPageView, FALSE);
289         }
290         else
291                 pRet = this->GetPDFWindow(pPageView, TRUE);
292         
293         m_pWidget->UpdateField();
294         
295         return pRet;
296 }
297
298 void CFFL_ListBox::OnKeyStroke(FX_BOOL bKeyDown, FX_DWORD nFlag)
299 {
300         ASSERT(m_pWidget != NULL);
301
302         int nFlags = m_pWidget->GetFieldFlags();
303         
304         if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
305         {
306                 if (m_bValid)
307                 {
308                         CPDFSDK_PageView* pPageView = this->GetCurPageView();
309                         ASSERT(pPageView != NULL);
310
311                         if (CommitData(pPageView, nFlag))
312                         {
313                                 DestroyPDFWindow(pPageView);
314                                 m_bValid = FALSE;
315                         }
316                 }
317         }
318 }
319