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