Cleanup: Do not check pointers before deleting them, part 2.
[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         if (CPWL_ComboBox * pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
89         {
90                 int32_t nCurSel = pWnd->GetSelect();
91
92                 ASSERT(m_pWidget != NULL);
93
94                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)
95                 {
96                         if (nCurSel >= 0)
97                         {
98                                 return nCurSel != m_pWidget->GetSelectedIndex(0);
99                         }
100                         else
101                         {
102                                 return pWnd->GetText() != m_pWidget->GetValue();
103                         }
104                 }
105                 else
106                 {
107                         return nCurSel != m_pWidget->GetSelectedIndex(0);
108                 }
109         }
110
111         return FALSE;
112 }
113
114 void CFFL_ComboBox::SaveData(CPDFSDK_PageView* pPageView)
115 {
116         ASSERT(m_pWidget != NULL);
117
118         if (CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
119         {
120                 CFX_WideString swText = pWnd->GetText();
121                 int32_t nCurSel = pWnd->GetSelect();
122
123                 //mantis:0004157
124                 FX_BOOL bSetValue = TRUE;
125
126                 if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)
127                 {
128                         if (nCurSel >= 0)
129                         {
130                                 if (swText != m_pWidget->GetOptionLabel(nCurSel))
131                                         bSetValue = TRUE;
132                                 else
133                                         bSetValue = FALSE;
134                         }
135                         else
136                                 bSetValue = TRUE;
137                 }
138                 else
139                         bSetValue = FALSE;
140
141                 CFX_WideString sOldValue;
142
143
144                 if (bSetValue)
145                 {
146                         sOldValue = m_pWidget->GetValue();
147                         m_pWidget->SetValue(swText, FALSE);
148                 }
149                 else
150                 {
151                         m_pWidget->GetSelectedIndex(0);
152                         m_pWidget->SetOptionSelection(nCurSel, TRUE, FALSE);
153                 }
154
155                 m_pWidget->ResetFieldAppearance(TRUE);
156                 m_pWidget->UpdateField();
157                 SetChangeMark();
158
159                 m_pWidget->GetPDFPage();
160
161
162         }
163 }
164
165  void CFFL_ComboBox::GetActionData( CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, PDFSDK_FieldAction& fa)
166 {
167         switch (type)
168         {
169         case CPDF_AAction::KeyStroke:
170                 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
171                 {
172                         if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
173                         {
174                                 fa.bFieldFull = pEdit->IsTextFull();
175                                 int nSelStart = 0;
176                                 int nSelEnd = 0;
177                                 pEdit->GetSel(nSelStart, nSelEnd);
178                                 fa.nSelEnd = nSelEnd;
179                                 fa.nSelStart = nSelStart;
180                                 fa.sValue = pEdit->GetText();
181                                 fa.sChangeEx = GetSelectExportText();
182
183                                 if (fa.bFieldFull)
184                                 {
185                                         fa.sChange = L"";
186                                         fa.sChangeEx = L"";
187                                 }
188                         }
189                 }
190                 break;
191         case CPDF_AAction::Validate:
192                 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
193                 {
194                         if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
195                         {
196                                 fa.sValue = pEdit->GetText();
197                         }
198                 }
199                 break;
200         case CPDF_AAction::LoseFocus:
201         case CPDF_AAction::GetFocus:
202                 ASSERT(m_pWidget != NULL);
203                 fa.sValue = m_pWidget->GetValue();
204                 break;
205         default:
206                 break;
207         }
208 }
209
210
211
212 void CFFL_ComboBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
213                                                                         const PDFSDK_FieldAction& fa)
214 {
215         switch (type)
216         {
217         case CPDF_AAction::KeyStroke:
218                 if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
219                 {
220                         if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
221                         {
222                                 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
223                                 pEdit->ReplaceSel(fa.sChange.c_str());
224                         }
225                 }
226                 break;
227         default:
228                 break;
229         }
230 }
231
232 FX_BOOL CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld,
233                                                                         const PDFSDK_FieldAction& faNew)
234 {
235         switch (type)
236         {
237         case CPDF_AAction::KeyStroke:
238                 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || faOld.nSelStart != faNew.nSelStart ||
239                         faOld.sChange != faNew.sChange;
240         default:
241                 break;
242         }
243
244         return FALSE;
245 }
246
247 void CFFL_ComboBox::SaveState(CPDFSDK_PageView* pPageView)
248 {
249         ASSERT(pPageView != NULL);
250
251         if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
252         {
253                 m_State.nIndex = pComboBox->GetSelect();
254
255                 if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
256                 {
257                         pEdit->GetSel(m_State.nStart, m_State.nEnd);
258                         m_State.sValue = pEdit->GetText();
259                 }
260         }
261 }
262
263 void CFFL_ComboBox::RestoreState(CPDFSDK_PageView* pPageView)
264 {
265         ASSERT(pPageView != NULL);
266
267         if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, TRUE))
268         {
269                 if (m_State.nIndex >= 0)
270                         pComboBox->SetSelect(m_State.nIndex);
271                 else
272                 {
273                         if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
274                         {
275                                 pEdit->SetText(m_State.sValue.c_str());
276                                 pEdit->SetSel(m_State.nStart, m_State.nEnd);
277                         }
278                 }
279         }
280 }
281
282 CPWL_Wnd* CFFL_ComboBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
283 {
284         if (bRestoreValue)
285                 SaveState(pPageView);
286
287         DestroyPDFWindow(pPageView);
288
289         CPWL_Wnd* pRet = NULL;
290
291         if (bRestoreValue)
292         {
293                 RestoreState(pPageView);
294                 pRet = GetPDFWindow(pPageView, FALSE);
295         }
296         else
297                 pRet = GetPDFWindow(pPageView, TRUE);
298
299         m_pWidget->UpdateField();
300
301         return pRet;
302 }
303
304 void CFFL_ComboBox::OnKeyStroke(FX_BOOL bKeyDown, FX_UINT nFlag)
305 {
306         ASSERT(m_pWidget != NULL);
307
308         int nFlags = m_pWidget->GetFieldFlags();
309
310         if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
311         {
312                 if (m_bValid)
313                 {
314                         CPDFSDK_PageView* pPageView = GetCurPageView();
315                         ASSERT(pPageView != NULL);
316
317                         if (CommitData(pPageView, nFlag))
318                         {
319                                 DestroyPDFWindow(pPageView);
320                                 m_bValid = FALSE;
321                         }
322                 }
323         }
324 }
325
326 void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd)
327 {
328         ASSERT(m_pApp != NULL);
329
330         ASSERT(pWnd != NULL);
331
332         if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT)
333         {
334                 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
335                 pEdit->SetCharSet(134);
336                 pEdit->SetCodePage(936);
337
338                 pEdit->SetReadyToInput();
339                 CFX_WideString wsText = pEdit->GetText();
340                 int nCharacters = wsText.GetLength();
341                 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
342                 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
343                 m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer, nCharacters, TRUE);
344
345                 pEdit->SetEditNotify(this);
346         }
347 }
348
349 void CFFL_ComboBox::OnKillFocus(CPWL_Wnd* pWnd)
350 {
351         ASSERT(m_pApp != NULL);
352 }
353
354 FX_BOOL CFFL_ComboBox::CanCopy(CPDFSDK_Document* pDocument)
355 {
356         ASSERT(pDocument != NULL);
357
358         return FALSE;
359 }
360
361 FX_BOOL CFFL_ComboBox::CanCut(CPDFSDK_Document* pDocument)
362 {
363         ASSERT(pDocument != NULL);
364
365         return FALSE;
366 }
367
368 FX_BOOL CFFL_ComboBox::CanPaste(CPDFSDK_Document* pDocument)
369 {
370         ASSERT(pDocument != NULL);
371
372         return FALSE;
373 }
374
375 void CFFL_ComboBox::OnAddUndo(CPWL_Edit* pEdit)
376 {
377         ASSERT(pEdit != NULL);
378 }
379
380 CFX_WideString CFFL_ComboBox::GetSelectExportText()
381 {
382         CFX_WideString swRet;
383
384         int nExport = -1;
385         CPDFSDK_PageView *pPageView = GetCurPageView();
386         if (CPWL_ComboBox * pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
387         {
388                 nExport = pComboBox->GetSelect();
389         }
390
391         if (nExport >= 0)
392         {
393                 if (CPDF_FormField * pFormField = m_pWidget->GetFormField())
394                 {
395                         swRet = pFormField->GetOptionValue(nExport);
396                         if (swRet.IsEmpty())
397                                 swRet = pFormField->GetOptionLabel(nExport);
398                 }
399         }
400
401         return swRet;
402 }