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