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