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