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