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_ListBox.h"
10//#include "../../include/formfiller/FFL_Module.h"
11#include "../../include/formfiller/FFL_IFormFiller.h"
12//#include "../../include/formfiller/FFL_Undo.h"
13#include "../../include/formfiller/FFL_CBA_Fontmap.h"
14
15
16#define	FFL_DEFAULTLISTBOXFONTSIZE		12.0f
17
18
19/* ------------------------------- CFFL_ListBox ------------------------------- */
20
21CFFL_ListBox::CFFL_ListBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
22	CFFL_FormFiller(pApp, pWidget),
23	m_pFontMap(NULL)
24{
25}
26
27CFFL_ListBox::~CFFL_ListBox()
28{
29	if (m_pFontMap)
30	{
31		delete m_pFontMap;
32		m_pFontMap = NULL;
33	}
34}
35
36PWL_CREATEPARAM	CFFL_ListBox::GetCreateParam()
37{
38	PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
39
40	ASSERT(m_pWidget != NULL);
41	FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
42
43	if (dwFieldFlag & FIELDFLAG_MULTISELECT)
44	{
45		cp.dwFlags |= PLBS_MULTIPLESEL;
46	}
47
48	if (dwFieldFlag & FIELDFLAG_COMMITONSELCHANGE)
49	{
50		//cp.dwFlags |= PLBS_COMMITSELECTEDVALUE;
51	}
52
53	cp.dwFlags |= PWS_VSCROLL;
54
55	if (cp.dwFlags & PWS_AUTOFONTSIZE)
56		cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE;
57
58	if (!m_pFontMap)
59	{
60		ASSERT(this->m_pApp != NULL);
61		m_pFontMap = new CBA_FontMap(m_pWidget,m_pApp->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pApp));
62		m_pFontMap->Initial();
63	}
64	cp.pFontMap = m_pFontMap;
65
66	return cp;
67}
68
69CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
70{
71	CPWL_ListBox* pWnd = new CPWL_ListBox();
72	pWnd->AttachFFLData(this);
73	pWnd->Create(cp);
74
75	ASSERT(m_pApp != NULL);
76	CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
77	pWnd->SetFillerNotify(pIFormFiller);
78
79	ASSERT(m_pWidget != NULL);
80
81	for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
82		pWnd->AddString(m_pWidget->GetOptionLabel(i));
83
84	if (pWnd->HasFlag(PLBS_MULTIPLESEL))
85	{
86		m_OriginSelections.RemoveAll();
87
88		FX_BOOL bSetCaret = FALSE;
89		for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
90		{
91			if (m_pWidget->IsOptionSelected(i))
92			{
93				if (!bSetCaret)
94				{
95					pWnd->SetCaret(i);
96					bSetCaret = TRUE;
97				}
98				pWnd->Select(i);
99				m_OriginSelections.SetAt(i, NULL);
100			}
101		}
102	}
103	else
104	{
105		for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
106		{
107			if (m_pWidget->IsOptionSelected(i))
108			{
109				pWnd->Select(i);
110				break;
111			}
112		}
113	}
114
115	pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
116
117	return pWnd;
118}
119
120
121FX_BOOL	CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
122{
123	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
124}
125
126FX_BOOL	CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView)
127{
128	ASSERT(m_pWidget != NULL);
129
130	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
131	{
132		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
133		{
134			int nSelCount = 0;
135			for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
136			{
137				if (pListBox->IsItemSelected(i))
138				{
139					void* p = NULL;
140					if (!m_OriginSelections.Lookup(i, p))
141						return TRUE;
142
143					nSelCount++;
144				}
145			}
146
147			return nSelCount != m_OriginSelections.GetCount();
148		}
149		else
150		{
151			return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
152		}
153	}
154
155	return FALSE;
156}
157
158void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView)
159{
160	ASSERT(m_pWidget != NULL);
161
162	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
163	{
164		CFX_IntArray aOldSelect, aNewSelect;
165
166		{
167			for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
168			{
169				if (m_pWidget->IsOptionSelected(i))
170				{
171					aOldSelect.Add(i);
172				}
173			}
174		}
175
176
177		FX_INT32 nNewTopIndex = pListBox->GetTopVisibleIndex();
178
179		m_pWidget->ClearSelection(FALSE);
180
181		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
182		{
183			for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
184			{
185				if (pListBox->IsItemSelected(i))
186				{
187					m_pWidget->SetOptionSelection(i, TRUE, FALSE);
188					aNewSelect.Add(i);
189				}
190			}
191		}
192		else
193		{
194			m_pWidget->SetOptionSelection(pListBox->GetCurSel(), TRUE, FALSE);
195			aNewSelect.Add(pListBox->GetCurSel());
196		}
197
198		m_pWidget->SetTopVisibleIndex(nNewTopIndex);
199		m_pWidget->ResetFieldAppearance(TRUE);
200		m_pWidget->UpdateField();
201		SetChangeMark();
202	}
203}
204
205void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
206						PDFSDK_FieldAction& fa)
207{
208	switch (type)
209	{
210	case CPDF_AAction::Validate:
211		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
212		{
213			fa.sValue = L"";
214		}
215		else
216		{
217			if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
218			{
219				ASSERT(m_pWidget != NULL);
220				FX_INT32 nCurSel = pListBox->GetCurSel();
221				if (nCurSel >= 0)
222					fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
223			}
224		}
225		break;
226	case CPDF_AAction::LoseFocus:
227	case CPDF_AAction::GetFocus:
228		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
229		{
230			fa.sValue = L"";
231		}
232		else
233		{
234			ASSERT(m_pWidget != NULL);
235			FX_INT32 nCurSel = m_pWidget->GetSelectedIndex(0);
236			if (nCurSel >= 0)
237				fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
238		}
239		break;
240	default:
241		break;
242	}
243}
244
245
246void CFFL_ListBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
247								const PDFSDK_FieldAction& fa)
248{
249}
250
251void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView)
252{
253	ASSERT(pPageView != NULL);
254
255	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
256	{
257		for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
258		{
259			if (pListBox->IsItemSelected(i))
260			{
261				m_State.Add(i);
262			}
263		}
264	}
265}
266
267void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView)
268{
269	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
270	{
271		for (int i=0,sz=m_State.GetSize(); i<sz; i++)
272			pListBox->Select(m_State[i]);
273	}
274}
275
276CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
277{
278	if (bRestoreValue)
279		SaveState(pPageView);
280
281	DestroyPDFWindow(pPageView);
282
283	CPWL_Wnd* pRet = NULL;
284
285	if (bRestoreValue)
286	{
287		RestoreState(pPageView);
288		pRet = this->GetPDFWindow(pPageView, FALSE);
289	}
290	else
291		pRet = this->GetPDFWindow(pPageView, TRUE);
292
293	m_pWidget->UpdateField();
294
295	return pRet;
296}
297
298void CFFL_ListBox::OnKeyStroke(FX_BOOL bKeyDown, FX_DWORD nFlag)
299{
300	ASSERT(m_pWidget != NULL);
301
302	int nFlags = m_pWidget->GetFieldFlags();
303
304	if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
305	{
306		if (m_bValid)
307		{
308			CPDFSDK_PageView* pPageView = this->GetCurPageView();
309			ASSERT(pPageView != NULL);
310
311			if (CommitData(pPageView, nFlag))
312			{
313				DestroyPDFWindow(pPageView);
314				m_bValid = FALSE;
315			}
316		}
317	}
318}
319
320