cffl_listbox.cpp revision 5ae9d0c6fd838a2967cca72aa5751b51dadc2769
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 "fpdfsdk/formfiller/cffl_listbox.h" 8 9#include "fpdfsdk/cpdfsdk_formfillenvironment.h" 10#include "fpdfsdk/cpdfsdk_widget.h" 11#include "fpdfsdk/formfiller/cba_fontmap.h" 12#include "fpdfsdk/formfiller/cffl_formfiller.h" 13#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h" 14#include "fpdfsdk/fsdk_common.h" 15#include "fpdfsdk/pdfwindow/PWL_ListBox.h" 16#include "third_party/base/ptr_util.h" 17 18#define FFL_DEFAULTLISTBOXFONTSIZE 12.0f 19 20CFFL_ListBox::CFFL_ListBox(CPDFSDK_FormFillEnvironment* pApp, 21 CPDFSDK_Annot* pWidget) 22 : CFFL_FormFiller(pApp, pWidget) {} 23 24CFFL_ListBox::~CFFL_ListBox() {} 25 26PWL_CREATEPARAM CFFL_ListBox::GetCreateParam() { 27 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam(); 28 29 uint32_t dwFieldFlag = m_pWidget->GetFieldFlags(); 30 31 if (dwFieldFlag & FIELDFLAG_MULTISELECT) { 32 cp.dwFlags |= PLBS_MULTIPLESEL; 33 } 34 35 cp.dwFlags |= PWS_VSCROLL; 36 37 if (cp.dwFlags & PWS_AUTOFONTSIZE) 38 cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE; 39 40 if (!m_pFontMap) { 41 m_pFontMap = pdfium::MakeUnique<CBA_FontMap>( 42 m_pWidget, m_pFormFillEnv->GetSysHandler()); 43 } 44 cp.pFontMap = m_pFontMap.get(); 45 46 return cp; 47} 48 49CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp, 50 CPDFSDK_PageView* pPageView) { 51 CPWL_ListBox* pWnd = new CPWL_ListBox(); 52 pWnd->AttachFFLData(this); 53 pWnd->Create(cp); 54 pWnd->SetFillerNotify(m_pFormFillEnv->GetInteractiveFormFiller()); 55 56 for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) 57 pWnd->AddString(m_pWidget->GetOptionLabel(i)); 58 59 if (pWnd->HasFlag(PLBS_MULTIPLESEL)) { 60 m_OriginSelections.clear(); 61 62 bool bSetCaret = false; 63 for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) { 64 if (m_pWidget->IsOptionSelected(i)) { 65 if (!bSetCaret) { 66 pWnd->SetCaret(i); 67 bSetCaret = true; 68 } 69 pWnd->Select(i); 70 m_OriginSelections.insert(i); 71 } 72 } 73 } else { 74 for (int i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) { 75 if (m_pWidget->IsOptionSelected(i)) { 76 pWnd->Select(i); 77 break; 78 } 79 } 80 } 81 82 pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex()); 83 84 return pWnd; 85} 86 87bool CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot, 88 uint32_t nChar, 89 uint32_t nFlags) { 90 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags); 91} 92 93bool CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView) { 94 CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, false); 95 if (!pListBox) 96 return false; 97 98 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) { 99 size_t nSelCount = 0; 100 for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; ++i) { 101 if (pListBox->IsItemSelected(i)) { 102 if (m_OriginSelections.count(i) == 0) 103 return true; 104 105 ++nSelCount; 106 } 107 } 108 109 return nSelCount != m_OriginSelections.size(); 110 } 111 return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0); 112} 113 114void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView) { 115 CPWL_ListBox* pListBox = 116 static_cast<CPWL_ListBox*>(GetPDFWindow(pPageView, false)); 117 if (!pListBox) 118 return; 119 120 int32_t nNewTopIndex = pListBox->GetTopVisibleIndex(); 121 m_pWidget->ClearSelection(false); 122 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) { 123 for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) { 124 if (pListBox->IsItemSelected(i)) 125 m_pWidget->SetOptionSelection(i, true, false); 126 } 127 } else { 128 m_pWidget->SetOptionSelection(pListBox->GetCurSel(), true, false); 129 } 130 m_pWidget->SetTopVisibleIndex(nNewTopIndex); 131 m_pWidget->ResetFieldAppearance(true); 132 m_pWidget->UpdateField(); 133 SetChangeMark(); 134} 135 136void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView, 137 CPDF_AAction::AActionType type, 138 PDFSDK_FieldAction& fa) { 139 switch (type) { 140 case CPDF_AAction::Validate: 141 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) { 142 fa.sValue = L""; 143 } else { 144 if (CPWL_ListBox* pListBox = 145 (CPWL_ListBox*)GetPDFWindow(pPageView, false)) { 146 int32_t nCurSel = pListBox->GetCurSel(); 147 if (nCurSel >= 0) 148 fa.sValue = m_pWidget->GetOptionLabel(nCurSel); 149 } 150 } 151 break; 152 case CPDF_AAction::LoseFocus: 153 case CPDF_AAction::GetFocus: 154 if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) { 155 fa.sValue = L""; 156 } else { 157 int32_t nCurSel = m_pWidget->GetSelectedIndex(0); 158 if (nCurSel >= 0) 159 fa.sValue = m_pWidget->GetOptionLabel(nCurSel); 160 } 161 break; 162 default: 163 break; 164 } 165} 166 167void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView) { 168 ASSERT(pPageView); 169 170 CPWL_ListBox* pListBox = 171 static_cast<CPWL_ListBox*>(GetPDFWindow(pPageView, false)); 172 if (!pListBox) 173 return; 174 175 for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) { 176 if (pListBox->IsItemSelected(i)) 177 m_State.push_back(i); 178 } 179} 180 181void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView) { 182 CPWL_ListBox* pListBox = 183 static_cast<CPWL_ListBox*>(GetPDFWindow(pPageView, false)); 184 if (!pListBox) 185 return; 186 187 for (const auto& item : m_State) 188 pListBox->Select(item); 189} 190 191CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, 192 bool bRestoreValue) { 193 if (bRestoreValue) 194 SaveState(pPageView); 195 196 DestroyPDFWindow(pPageView); 197 198 CPWL_Wnd* pRet = nullptr; 199 200 if (bRestoreValue) { 201 RestoreState(pPageView); 202 pRet = GetPDFWindow(pPageView, false); 203 } else { 204 pRet = GetPDFWindow(pPageView, true); 205 } 206 207 m_pWidget->UpdateField(); 208 209 return pRet; 210} 211