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