3f2c453e5d9517f3c1db253069c681befb4477b8
[pdfium.git] / fpdfsdk / src / formfiller / FFL_ComboBox.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_IFormFiller.h"\r
10 #include "../../include/formfiller/FFL_CBA_Fontmap.h"\r
11 #include "../../include/formfiller/FFL_ComboBox.h"\r
12 \r
13 \r
14 /* ------------------------------- CFFL_ComboBox ------------------------------- */\r
15 \r
16 CFFL_ComboBox::CFFL_ComboBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot) :\r
17         CFFL_FormFiller(pApp, pAnnot), m_pFontMap( NULL )\r
18 {\r
19         //m_pFontMap = new CBA_FontMap( pAnnot, GetSystemHandler() );\r
20         m_State.nIndex = 0;\r
21         m_State.nStart = 0;\r
22         m_State.nEnd   = 0;\r
23 }\r
24 \r
25 CFFL_ComboBox::~CFFL_ComboBox()\r
26 {\r
27         if (m_pFontMap)\r
28         {\r
29                 delete m_pFontMap;\r
30                 m_pFontMap = NULL;\r
31         }\r
32 \r
33 //      for (int i=0,sz=m_IMBox.GetSize(); i<sz; i++)\r
34 //      {\r
35 //              delete m_IMBox.GetAt(i);\r
36 //      }\r
37 // \r
38 //      m_IMBox.RemoveAll();\r
39 }\r
40 \r
41 PWL_CREATEPARAM CFFL_ComboBox::GetCreateParam()\r
42 {\r
43         PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();\r
44 \r
45         ASSERT(m_pWidget != NULL);\r
46 \r
47         int nFlags = m_pWidget->GetFieldFlags();\r
48         \r
49         if (nFlags & FIELDFLAG_EDIT)\r
50         {               \r
51                 cp.dwFlags |= PCBS_ALLOWCUSTOMTEXT;\r
52         }\r
53 \r
54         /*\r
55         if (nFlags & FIELDFLAG_COMMITONSELCHANGE)\r
56         {               \r
57                 m_bCommitOnSelectChange = TRUE;\r
58         }\r
59         */\r
60 \r
61         if (!m_pFontMap)\r
62         {\r
63                 ASSERT(this->m_pApp != NULL);\r
64                 m_pFontMap = new CBA_FontMap(m_pWidget, GetSystemHandler());\r
65                 m_pFontMap->Initial();\r
66         }\r
67 \r
68         cp.pFontMap = m_pFontMap;\r
69         cp.pFocusHandler = this;\r
70 \r
71         return cp;\r
72 }\r
73 \r
74 CPWL_Wnd* CFFL_ComboBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)\r
75 {\r
76         CPWL_ComboBox * pWnd = new CPWL_ComboBox();\r
77         pWnd->AttachFFLData(this);\r
78         pWnd->Create(cp);\r
79 \r
80         ASSERT(m_pApp != NULL);\r
81         CFFL_IFormFiller* pFormFiller = m_pApp->GetIFormFiller();\r
82         pWnd->SetFillerNotify(pFormFiller);\r
83 \r
84         ASSERT(m_pWidget != NULL);\r
85         FX_INT32 nCurSel = m_pWidget->GetSelectedIndex(0);\r
86         \r
87         CFX_WideString swText;\r
88         \r
89         if (nCurSel < 0)\r
90                 swText = m_pWidget->GetValue();\r
91         else\r
92                 swText = m_pWidget->GetOptionLabel(nCurSel);\r
93         \r
94         for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)\r
95         {\r
96                 pWnd->AddString(m_pWidget->GetOptionLabel(i));                  \r
97         }\r
98         \r
99         pWnd->SetSelect(nCurSel);\r
100         pWnd->SetText(swText);\r
101         \r
102         return pWnd;\r
103 }\r
104 \r
105 \r
106 FX_BOOL CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)\r
107 {\r
108         return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);\r
109 }\r
110 \r
111 FX_BOOL CFFL_ComboBox::IsDataChanged(CPDFSDK_PageView* pPageView)\r
112 {\r
113         if (CPWL_ComboBox * pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))\r
114         {\r
115                 FX_INT32 nCurSel = pWnd->GetSelect();\r
116 \r
117                 ASSERT(m_pWidget != NULL);\r
118 \r
119                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)\r
120                 {\r
121                         if (nCurSel >= 0)\r
122                         {\r
123                                 return nCurSel != m_pWidget->GetSelectedIndex(0);\r
124                         }\r
125                         else\r
126                         {\r
127                                 return pWnd->GetText() != m_pWidget->GetValue();\r
128                         }\r
129                 }\r
130                 else\r
131                 {\r
132                         return nCurSel != m_pWidget->GetSelectedIndex(0);\r
133                 }\r
134         }\r
135         \r
136         return FALSE;\r
137 }\r
138 \r
139 void CFFL_ComboBox::SaveData(CPDFSDK_PageView* pPageView)\r
140 {\r
141         ASSERT(m_pWidget != NULL);\r
142 \r
143         if (CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))\r
144         {\r
145                 CFX_WideString swText = pWnd->GetText();\r
146                 FX_INT32 nCurSel = pWnd->GetSelect();\r
147 \r
148                 //mantis:0004157\r
149                 FX_BOOL bSetValue = TRUE;\r
150 \r
151                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)\r
152                 {\r
153                         if (nCurSel >= 0)\r
154                         {\r
155                                 if (swText != m_pWidget->GetOptionLabel(nCurSel))\r
156                                         bSetValue = TRUE;\r
157                                 else\r
158                                         bSetValue = FALSE;\r
159                         }\r
160                         else\r
161                                 bSetValue = TRUE;\r
162                 }\r
163                 else\r
164                         bSetValue = FALSE;\r
165 \r
166                 CFX_WideString sOldValue;\r
167                 \r
168 \r
169                 if (bSetValue)\r
170                 {\r
171                         sOldValue = m_pWidget->GetValue();\r
172                         m_pWidget->SetValue(swText, FALSE);\r
173                 }\r
174                 else\r
175                 {\r
176                         m_pWidget->GetSelectedIndex(0);\r
177                         m_pWidget->SetOptionSelection(nCurSel, TRUE, FALSE);\r
178                 }\r
179 \r
180                 m_pWidget->ResetFieldAppearance(TRUE);\r
181                 m_pWidget->UpdateField();\r
182                 SetChangeMark();\r
183 \r
184                 m_pWidget->GetPDFPage();\r
185                 \r
186 \r
187         }\r
188 }\r
189 \r
190  void CFFL_ComboBox::GetActionData( CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, PDFSDK_FieldAction& fa)\r
191 {\r
192         switch (type)\r
193         {\r
194         case CPDF_AAction::KeyStroke:\r
195                 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))\r
196                 {\r
197                         if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)\r
198                         {\r
199                                 fa.bFieldFull = pEdit->IsTextFull();    \r
200                                 int nSelStart = 0;\r
201                                 int nSelEnd = 0;\r
202                                 pEdit->GetSel(nSelStart, nSelEnd);\r
203                                 fa.nSelEnd = nSelEnd;\r
204                                 fa.nSelStart = nSelStart;\r
205                                 fa.sValue = pEdit->GetText();\r
206                                 fa.sChangeEx = GetSelectExportText();\r
207 \r
208                                 if (fa.bFieldFull)\r
209                                 {\r
210                                         fa.sChange = L"";\r
211                                         fa.sChangeEx = L"";\r
212                                 }\r
213                         }\r
214                 }\r
215                 break;\r
216         case CPDF_AAction::Validate:\r
217                 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))\r
218                 {\r
219                         if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)\r
220                         {\r
221                                 fa.sValue = pEdit->GetText();\r
222                         }\r
223                 }\r
224                 break;\r
225         case CPDF_AAction::LoseFocus:\r
226         case CPDF_AAction::GetFocus:\r
227                 ASSERT(m_pWidget != NULL);\r
228                 fa.sValue = m_pWidget->GetValue();\r
229                 break;\r
230         default:\r
231                 break;\r
232         }\r
233 }\r
234 \r
235 \r
236 \r
237 void CFFL_ComboBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, \r
238                                                                         const PDFSDK_FieldAction& fa)\r
239 {\r
240         switch (type)\r
241         {\r
242         case CPDF_AAction::KeyStroke:\r
243                 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))\r
244                 {\r
245                         if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)\r
246                         {\r
247                                 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);\r
248                                 pEdit->ReplaceSel(fa.sChange);\r
249                         }\r
250                 }\r
251                 break;\r
252         default:\r
253                 break;\r
254         }\r
255 }\r
256 \r
257 FX_BOOL CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld, \r
258                                                                         const PDFSDK_FieldAction& faNew)\r
259 {\r
260         switch (type)\r
261         {\r
262         case CPDF_AAction::KeyStroke:\r
263                 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || faOld.nSelStart != faNew.nSelStart ||\r
264                         faOld.sChange != faNew.sChange;\r
265         default:\r
266                 break;\r
267         }\r
268 \r
269         return FALSE;\r
270 }\r
271 \r
272 void CFFL_ComboBox::SaveState(CPDFSDK_PageView* pPageView)\r
273 {\r
274         ASSERT(pPageView != NULL);\r
275 \r
276         if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))\r
277         {\r
278                 m_State.nIndex = pComboBox->GetSelect();\r
279 \r
280                 if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)\r
281                 {\r
282                         pEdit->GetSel(m_State.nStart, m_State.nEnd);\r
283                         m_State.sValue = pEdit->GetText();\r
284                 }\r
285         }\r
286 }\r
287 \r
288 void CFFL_ComboBox::RestoreState(CPDFSDK_PageView* pPageView)\r
289 {\r
290         ASSERT(pPageView != NULL);\r
291 \r
292         if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, TRUE))\r
293         {\r
294                 if (m_State.nIndex >= 0)\r
295                         pComboBox->SetSelect(m_State.nIndex);\r
296                 else\r
297                 {\r
298                         if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)\r
299                         {\r
300                                 pEdit->SetText(m_State.sValue);\r
301                                 pEdit->SetSel(m_State.nStart, m_State.nEnd);\r
302                         }\r
303                 }\r
304         }\r
305 }\r
306 \r
307 CPWL_Wnd* CFFL_ComboBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)\r
308 {\r
309         if (bRestoreValue)\r
310                 SaveState(pPageView);\r
311         \r
312         DestroyPDFWindow(pPageView);\r
313         \r
314         CPWL_Wnd* pRet = NULL;\r
315         \r
316         if (bRestoreValue)\r
317         {\r
318                 RestoreState(pPageView);\r
319                 pRet = this->GetPDFWindow(pPageView, FALSE);\r
320         }\r
321         else\r
322                 pRet = this->GetPDFWindow(pPageView, TRUE);\r
323         \r
324         m_pWidget->UpdateField();\r
325         \r
326         return pRet;\r
327 }\r
328 \r
329 void CFFL_ComboBox::OnKeyStroke(FX_BOOL bKeyDown, FX_UINT nFlag)\r
330 {\r
331         ASSERT(m_pWidget != NULL);\r
332         \r
333         int nFlags = m_pWidget->GetFieldFlags();\r
334         \r
335         if (nFlags & FIELDFLAG_COMMITONSELCHANGE)\r
336         {\r
337                 if (m_bValid)\r
338                 {\r
339                         CPDFSDK_PageView* pPageView = this->GetCurPageView();\r
340                         ASSERT(pPageView != NULL);\r
341 \r
342                         if (CommitData(pPageView, nFlag))\r
343                         {\r
344                                 DestroyPDFWindow(pPageView);\r
345                                 m_bValid = FALSE;\r
346                         }\r
347                 }\r
348         }\r
349 }\r
350 \r
351 void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd)\r
352 {\r
353         ASSERT(m_pApp != NULL);\r
354 \r
355         ASSERT(pWnd != NULL);\r
356 \r
357         if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT)\r
358         {\r
359                 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;\r
360                 pEdit->SetCharSet(134);\r
361                 pEdit->SetCodePage(936);\r
362 \r
363                 pEdit->SetReadyToInput();\r
364                 CFX_WideString wsText = pEdit->GetText();\r
365                 int nCharacters = wsText.GetLength();\r
366                 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();\r
367                 unsigned short* pBuffer = (unsigned short*)(FX_LPCSTR)bsUTFText;\r
368                 m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer, nCharacters, TRUE);\r
369 \r
370                 pEdit->SetEditNotify(this);\r
371         }\r
372 }\r
373 \r
374 void CFFL_ComboBox::OnKillFocus(CPWL_Wnd* pWnd)\r
375 {\r
376         ASSERT(m_pApp != NULL);\r
377 }\r
378 \r
379 FX_BOOL CFFL_ComboBox::CanCopy(CPDFSDK_Document* pDocument)\r
380 {\r
381         ASSERT(pDocument != NULL);\r
382 \r
383         return FALSE;\r
384 }\r
385 \r
386 FX_BOOL CFFL_ComboBox::CanCut(CPDFSDK_Document* pDocument)\r
387 {\r
388         ASSERT(pDocument != NULL);\r
389 \r
390         return FALSE;\r
391 }\r
392 \r
393 FX_BOOL CFFL_ComboBox::CanPaste(CPDFSDK_Document* pDocument)\r
394 {\r
395         ASSERT(pDocument != NULL);\r
396 \r
397         return FALSE;\r
398 }\r
399 \r
400 void CFFL_ComboBox::DoCopy(CPDFSDK_Document* pDocument)\r
401 {\r
402         ASSERT(pDocument != NULL);\r
403 }\r
404 \r
405 void CFFL_ComboBox::DoCut(CPDFSDK_Document* pDocument)\r
406 {\r
407         ASSERT(pDocument != NULL);\r
408 }\r
409 \r
410 void CFFL_ComboBox::DoPaste(CPDFSDK_Document* pDocument)\r
411 {\r
412         ASSERT(pDocument != NULL);\r
413 }\r
414 \r
415 void CFFL_ComboBox::OnAddUndo(CPWL_Edit* pEdit)\r
416 {\r
417         ASSERT(pEdit != NULL);\r
418 }\r
419 \r
420 CFX_WideString CFFL_ComboBox::GetSelectExportText()\r
421 {\r
422         CFX_WideString swRet;\r
423         \r
424         int nExport = -1;\r
425         CPDFSDK_PageView *pPageView = GetCurPageView();\r
426         if (CPWL_ComboBox * pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))\r
427         {\r
428                 nExport = pComboBox->GetSelect();\r
429         }\r
430         \r
431         if (nExport >= 0)\r
432         {\r
433                 if (CPDF_FormField * pFormField = m_pWidget->GetFormField())\r
434                 {\r
435                         swRet = pFormField->GetOptionValue(nExport);\r
436                         if (swRet.IsEmpty())\r
437                                 swRet = pFormField->GetOptionLabel(nExport);\r
438                 }\r
439         }\r
440         \r
441         return swRet;\r
442 }\r