summaryrefslogtreecommitdiff
path: root/fpdfsdk/pdfwindow/cpwl_list_impl.cpp
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2017-07-24 09:42:55 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-07-24 13:59:00 +0000
commit6b0158fdc229e7fc45fdb61c700b709bd82b2309 (patch)
treeacb36f7f20b7a1280613deae74bcedcd500f3547 /fpdfsdk/pdfwindow/cpwl_list_impl.cpp
parentc08dc39850188d96ad81f5800c7a51d2663eeb44 (diff)
downloadpdfium-6b0158fdc229e7fc45fdb61c700b709bd82b2309.tar.xz
Remove fxedit place classes in pdfwindow/
This CL removes the fpdfsdk/fxedit folder and moves the code to fpdfsdk/pdfwindow which is the primary consumer. The classes were renamed from CFX_* to CPWL_*. Change-Id: I6c6178adccf978193bbb9685204657ebd3f438bb Reviewed-on: https://pdfium-review.googlesource.com/8552 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'fpdfsdk/pdfwindow/cpwl_list_impl.cpp')
-rw-r--r--fpdfsdk/pdfwindow/cpwl_list_impl.cpp637
1 files changed, 637 insertions, 0 deletions
diff --git a/fpdfsdk/pdfwindow/cpwl_list_impl.cpp b/fpdfsdk/pdfwindow/cpwl_list_impl.cpp
new file mode 100644
index 0000000000..66b2e77747
--- /dev/null
+++ b/fpdfsdk/pdfwindow/cpwl_list_impl.cpp
@@ -0,0 +1,637 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/pdfwindow/cpwl_list_impl.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "core/fpdfdoc/cpvt_word.h"
+#include "core/fxcrt/fx_extension.h"
+#include "fpdfsdk/pdfwindow/cpwl_edit_impl.h"
+#include "fpdfsdk/pdfwindow/cpwl_list_box.h"
+#include "third_party/base/stl_util.h"
+
+CPWL_ListCtrl::Item::Item()
+ : m_pEdit(new CPWL_EditImpl),
+ m_bSelected(false),
+ m_rcListItem(0.0f, 0.0f, 0.0f, 0.0f) {
+ m_pEdit->SetAlignmentV(1, true);
+ m_pEdit->Initialize();
+}
+
+CPWL_ListCtrl::Item::~Item() {}
+
+void CPWL_ListCtrl::Item::SetFontMap(IPVT_FontMap* pFontMap) {
+ m_pEdit->SetFontMap(pFontMap);
+}
+
+void CPWL_ListCtrl::Item::SetText(const CFX_WideString& text) {
+ m_pEdit->SetText(text);
+}
+
+void CPWL_ListCtrl::Item::SetFontSize(float fFontSize) {
+ m_pEdit->SetFontSize(fFontSize);
+}
+
+float CPWL_ListCtrl::Item::GetItemHeight() const {
+ return m_pEdit->GetContentRect().Height();
+}
+
+uint16_t CPWL_ListCtrl::Item::GetFirstChar() const {
+ CPVT_Word word;
+ CPWL_EditImpl_Iterator* pIterator = m_pEdit->GetIterator();
+ pIterator->SetAt(1);
+ pIterator->GetWord(word);
+ return word.Word;
+}
+
+CFX_WideString CPWL_ListCtrl::Item::GetText() const {
+ return m_pEdit->GetText();
+}
+
+CPLST_Select::CPLST_Select() {}
+
+CPLST_Select::~CPLST_Select() {}
+
+void CPLST_Select::Add(int32_t nItemIndex) {
+ m_Items[nItemIndex] = SELECTING;
+}
+
+void CPLST_Select::Add(int32_t nBeginIndex, int32_t nEndIndex) {
+ if (nBeginIndex > nEndIndex)
+ std::swap(nBeginIndex, nEndIndex);
+
+ for (int32_t i = nBeginIndex; i <= nEndIndex; ++i)
+ Add(i);
+}
+
+void CPLST_Select::Sub(int32_t nItemIndex) {
+ auto it = m_Items.find(nItemIndex);
+ if (it != m_Items.end())
+ it->second = DESELECTING;
+}
+
+void CPLST_Select::Sub(int32_t nBeginIndex, int32_t nEndIndex) {
+ if (nBeginIndex > nEndIndex)
+ std::swap(nBeginIndex, nEndIndex);
+
+ for (int32_t i = nBeginIndex; i <= nEndIndex; ++i)
+ Sub(i);
+}
+
+void CPLST_Select::DeselectAll() {
+ for (auto& item : m_Items)
+ item.second = DESELECTING;
+}
+
+void CPLST_Select::Done() {
+ auto it = m_Items.begin();
+ while (it != m_Items.end()) {
+ if (it->second == DESELECTING)
+ it = m_Items.erase(it);
+ else
+ (it++)->second = NORMAL;
+ }
+}
+
+CPWL_ListCtrl::CPWL_ListCtrl()
+ : m_pNotify(nullptr),
+ m_bNotifyFlag(false),
+ m_nSelItem(-1),
+ m_nFootIndex(-1),
+ m_bCtrlSel(false),
+ m_nCaretIndex(-1),
+ m_fFontSize(0.0f),
+ m_pFontMap(nullptr),
+ m_bMultiple(false) {}
+
+CPWL_ListCtrl::~CPWL_ListCtrl() {
+ Empty();
+}
+
+CFX_PointF CPWL_ListCtrl::InToOut(const CFX_PointF& point) const {
+ CFX_FloatRect rcPlate = m_rcPlate;
+ return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
+ point.y - (m_ptScrollPos.y - rcPlate.top));
+}
+
+CFX_PointF CPWL_ListCtrl::OutToIn(const CFX_PointF& point) const {
+ CFX_FloatRect rcPlate = m_rcPlate;
+ return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
+ point.y + (m_ptScrollPos.y - rcPlate.top));
+}
+
+CFX_FloatRect CPWL_ListCtrl::InToOut(const CFX_FloatRect& rect) const {
+ CFX_PointF ptLeftBottom = InToOut(CFX_PointF(rect.left, rect.bottom));
+ CFX_PointF ptRightTop = InToOut(CFX_PointF(rect.right, rect.top));
+ return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
+ ptRightTop.y);
+}
+
+CFX_FloatRect CPWL_ListCtrl::OutToIn(const CFX_FloatRect& rect) const {
+ CFX_PointF ptLeftBottom = OutToIn(CFX_PointF(rect.left, rect.bottom));
+ CFX_PointF ptRightTop = OutToIn(CFX_PointF(rect.right, rect.top));
+ return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
+ ptRightTop.y);
+}
+
+CFX_PointF CPWL_ListCtrl::InnerToOuter(const CFX_PointF& point) const {
+ return CFX_PointF(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
+}
+
+CFX_PointF CPWL_ListCtrl::OuterToInner(const CFX_PointF& point) const {
+ return CFX_PointF(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
+}
+
+CFX_FloatRect CPWL_ListCtrl::InnerToOuter(const CFX_FloatRect& rect) const {
+ CFX_PointF ptLeftTop = InnerToOuter(CFX_PointF(rect.left, rect.top));
+ CFX_PointF ptRightBottom = InnerToOuter(CFX_PointF(rect.right, rect.bottom));
+ return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
+ ptLeftTop.y);
+}
+
+CFX_FloatRect CPWL_ListCtrl::OuterToInner(const CFX_FloatRect& rect) const {
+ CFX_PointF ptLeftTop = OuterToInner(CFX_PointF(rect.left, rect.top));
+ CFX_PointF ptRightBottom = OuterToInner(CFX_PointF(rect.right, rect.bottom));
+ return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
+ ptLeftTop.y);
+}
+
+void CPWL_ListCtrl::OnMouseDown(const CFX_PointF& point,
+ bool bShift,
+ bool bCtrl) {
+ int32_t nHitIndex = GetItemIndex(point);
+
+ if (IsMultipleSel()) {
+ if (bCtrl) {
+ if (IsItemSelected(nHitIndex)) {
+ m_aSelItems.Sub(nHitIndex);
+ SelectItems();
+ m_bCtrlSel = false;
+ } else {
+ m_aSelItems.Add(nHitIndex);
+ SelectItems();
+ m_bCtrlSel = true;
+ }
+
+ m_nFootIndex = nHitIndex;
+ } else if (bShift) {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(m_nFootIndex, nHitIndex);
+ SelectItems();
+ } else {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(nHitIndex);
+ SelectItems();
+
+ m_nFootIndex = nHitIndex;
+ }
+
+ SetCaret(nHitIndex);
+ } else {
+ SetSingleSelect(nHitIndex);
+ }
+
+ if (!IsItemVisible(nHitIndex))
+ ScrollToListItem(nHitIndex);
+}
+
+void CPWL_ListCtrl::OnMouseMove(const CFX_PointF& point,
+ bool bShift,
+ bool bCtrl) {
+ int32_t nHitIndex = GetItemIndex(point);
+
+ if (IsMultipleSel()) {
+ if (bCtrl) {
+ if (m_bCtrlSel)
+ m_aSelItems.Add(m_nFootIndex, nHitIndex);
+ else
+ m_aSelItems.Sub(m_nFootIndex, nHitIndex);
+
+ SelectItems();
+ } else {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(m_nFootIndex, nHitIndex);
+ SelectItems();
+ }
+
+ SetCaret(nHitIndex);
+ } else {
+ SetSingleSelect(nHitIndex);
+ }
+
+ if (!IsItemVisible(nHitIndex))
+ ScrollToListItem(nHitIndex);
+}
+
+void CPWL_ListCtrl::OnVK(int32_t nItemIndex, bool bShift, bool bCtrl) {
+ if (IsMultipleSel()) {
+ if (nItemIndex >= 0 && nItemIndex < GetCount()) {
+ if (bCtrl) {
+ } else if (bShift) {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(m_nFootIndex, nItemIndex);
+ SelectItems();
+ } else {
+ m_aSelItems.DeselectAll();
+ m_aSelItems.Add(nItemIndex);
+ SelectItems();
+ m_nFootIndex = nItemIndex;
+ }
+
+ SetCaret(nItemIndex);
+ }
+ } else {
+ SetSingleSelect(nItemIndex);
+ }
+
+ if (!IsItemVisible(nItemIndex))
+ ScrollToListItem(nItemIndex);
+}
+
+void CPWL_ListCtrl::OnVK_UP(bool bShift, bool bCtrl) {
+ OnVK(IsMultipleSel() ? GetCaret() - 1 : GetSelect() - 1, bShift, bCtrl);
+}
+
+void CPWL_ListCtrl::OnVK_DOWN(bool bShift, bool bCtrl) {
+ OnVK(IsMultipleSel() ? GetCaret() + 1 : GetSelect() + 1, bShift, bCtrl);
+}
+
+void CPWL_ListCtrl::OnVK_LEFT(bool bShift, bool bCtrl) {
+ OnVK(0, bShift, bCtrl);
+}
+
+void CPWL_ListCtrl::OnVK_RIGHT(bool bShift, bool bCtrl) {
+ OnVK(GetCount() - 1, bShift, bCtrl);
+}
+
+void CPWL_ListCtrl::OnVK_HOME(bool bShift, bool bCtrl) {
+ OnVK(0, bShift, bCtrl);
+}
+
+void CPWL_ListCtrl::OnVK_END(bool bShift, bool bCtrl) {
+ OnVK(GetCount() - 1, bShift, bCtrl);
+}
+
+bool CPWL_ListCtrl::OnChar(uint16_t nChar, bool bShift, bool bCtrl) {
+ int32_t nIndex = GetLastSelected();
+ int32_t nFindIndex = FindNext(nIndex, nChar);
+
+ if (nFindIndex != nIndex) {
+ OnVK(nFindIndex, bShift, bCtrl);
+ return true;
+ }
+ return false;
+}
+
+void CPWL_ListCtrl::SetPlateRect(const CFX_FloatRect& rect) {
+ m_rcPlate = rect;
+ m_ptScrollPos.x = rect.left;
+ SetScrollPos(CFX_PointF(rect.left, rect.top));
+ ReArrange(0);
+ InvalidateItem(-1);
+}
+
+CFX_FloatRect CPWL_ListCtrl::GetItemRect(int32_t nIndex) const {
+ return InToOut(GetItemRectInternal(nIndex));
+}
+
+CFX_FloatRect CPWL_ListCtrl::GetItemRectInternal(int32_t nIndex) const {
+ if (!pdfium::IndexInBounds(m_ListItems, nIndex) || !m_ListItems[nIndex])
+ return CFX_FloatRect();
+
+ CFX_FloatRect rcItem = m_ListItems[nIndex]->GetRect();
+ rcItem.left = 0.0f;
+ rcItem.right = m_rcPlate.Width();
+ return InnerToOuter(rcItem);
+}
+
+void CPWL_ListCtrl::AddString(const CFX_WideString& str) {
+ AddItem(str);
+ ReArrange(GetCount() - 1);
+}
+
+void CPWL_ListCtrl::SetMultipleSelect(int32_t nItemIndex, bool bSelected) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ if (bSelected != IsItemSelected(nItemIndex)) {
+ if (bSelected) {
+ SetItemSelect(nItemIndex, true);
+ InvalidateItem(nItemIndex);
+ } else {
+ SetItemSelect(nItemIndex, false);
+ InvalidateItem(nItemIndex);
+ }
+ }
+}
+
+void CPWL_ListCtrl::SetSingleSelect(int32_t nItemIndex) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ if (m_nSelItem != nItemIndex) {
+ if (m_nSelItem >= 0) {
+ SetItemSelect(m_nSelItem, false);
+ InvalidateItem(m_nSelItem);
+ }
+
+ SetItemSelect(nItemIndex, true);
+ InvalidateItem(nItemIndex);
+ m_nSelItem = nItemIndex;
+ }
+}
+
+void CPWL_ListCtrl::SetCaret(int32_t nItemIndex) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ if (IsMultipleSel()) {
+ int32_t nOldIndex = m_nCaretIndex;
+
+ if (nOldIndex != nItemIndex) {
+ m_nCaretIndex = nItemIndex;
+ InvalidateItem(nOldIndex);
+ InvalidateItem(nItemIndex);
+ }
+ }
+}
+
+void CPWL_ListCtrl::InvalidateItem(int32_t nItemIndex) {
+ if (m_pNotify) {
+ if (nItemIndex == -1) {
+ if (!m_bNotifyFlag) {
+ m_bNotifyFlag = true;
+ CFX_FloatRect rcRefresh = m_rcPlate;
+ m_pNotify->IOnInvalidateRect(&rcRefresh);
+ m_bNotifyFlag = false;
+ }
+ } else {
+ if (!m_bNotifyFlag) {
+ m_bNotifyFlag = true;
+ CFX_FloatRect rcRefresh = GetItemRect(nItemIndex);
+ rcRefresh.left -= 1.0f;
+ rcRefresh.right += 1.0f;
+ rcRefresh.bottom -= 1.0f;
+ rcRefresh.top += 1.0f;
+
+ m_pNotify->IOnInvalidateRect(&rcRefresh);
+ m_bNotifyFlag = false;
+ }
+ }
+ }
+}
+
+void CPWL_ListCtrl::SelectItems() {
+ for (const auto& item : m_aSelItems) {
+ if (item.second != CPLST_Select::NORMAL)
+ SetMultipleSelect(item.first, item.second == CPLST_Select::SELECTING);
+ }
+ m_aSelItems.Done();
+}
+
+void CPWL_ListCtrl::Select(int32_t nItemIndex) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ if (IsMultipleSel()) {
+ m_aSelItems.Add(nItemIndex);
+ SelectItems();
+ } else {
+ SetSingleSelect(nItemIndex);
+ }
+}
+
+bool CPWL_ListCtrl::IsItemVisible(int32_t nItemIndex) const {
+ CFX_FloatRect rcPlate = m_rcPlate;
+ CFX_FloatRect rcItem = GetItemRect(nItemIndex);
+
+ return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top;
+}
+
+void CPWL_ListCtrl::ScrollToListItem(int32_t nItemIndex) {
+ if (!IsValid(nItemIndex))
+ return;
+
+ CFX_FloatRect rcPlate = m_rcPlate;
+ CFX_FloatRect rcItem = GetItemRectInternal(nItemIndex);
+ CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex);
+
+ if (IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
+ if (IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
+ SetScrollPosY(rcItem.bottom + rcPlate.Height());
+ }
+ } else if (IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
+ if (IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
+ SetScrollPosY(rcItem.top);
+ }
+ }
+}
+
+void CPWL_ListCtrl::SetScrollInfo() {
+ if (m_pNotify) {
+ CFX_FloatRect rcPlate = m_rcPlate;
+ CFX_FloatRect rcContent = GetContentRectInternal();
+
+ if (!m_bNotifyFlag) {
+ m_bNotifyFlag = true;
+ m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
+ rcContent.bottom, rcContent.top,
+ GetFirstHeight(), rcPlate.Height());
+ m_bNotifyFlag = false;
+ }
+ }
+}
+
+void CPWL_ListCtrl::SetScrollPos(const CFX_PointF& point) {
+ SetScrollPosY(point.y);
+}
+
+void CPWL_ListCtrl::SetScrollPosY(float fy) {
+ if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
+ CFX_FloatRect rcPlate = m_rcPlate;
+ CFX_FloatRect rcContent = GetContentRectInternal();
+
+ if (rcPlate.Height() > rcContent.Height()) {
+ fy = rcPlate.top;
+ } else {
+ if (IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
+ fy = rcContent.bottom + rcPlate.Height();
+ } else if (IsFloatBigger(fy, rcContent.top)) {
+ fy = rcContent.top;
+ }
+ }
+
+ m_ptScrollPos.y = fy;
+ InvalidateItem(-1);
+
+ if (m_pNotify) {
+ if (!m_bNotifyFlag) {
+ m_bNotifyFlag = true;
+ m_pNotify->IOnSetScrollPosY(fy);
+ m_bNotifyFlag = false;
+ }
+ }
+ }
+}
+
+CFX_FloatRect CPWL_ListCtrl::GetContentRectInternal() const {
+ return InnerToOuter(m_rcContent);
+}
+
+CFX_FloatRect CPWL_ListCtrl::GetContentRect() const {
+ return InToOut(GetContentRectInternal());
+}
+
+void CPWL_ListCtrl::ReArrange(int32_t nItemIndex) {
+ float fPosY = 0.0f;
+ if (pdfium::IndexInBounds(m_ListItems, nItemIndex - 1) &&
+ m_ListItems[nItemIndex - 1]) {
+ fPosY = m_ListItems[nItemIndex - 1]->GetRect().bottom;
+ }
+ for (const auto& pListItem : m_ListItems) {
+ if (pListItem) {
+ float fListItemHeight = pListItem->GetItemHeight();
+ pListItem->SetRect(
+ CFX_FloatRect(0.0f, fPosY + fListItemHeight, 0.0f, fPosY));
+ fPosY += fListItemHeight;
+ }
+ }
+ SetContentRect(CFX_FloatRect(0.0f, fPosY, 0.0f, 0.0f));
+ SetScrollInfo();
+}
+
+void CPWL_ListCtrl::SetTopItem(int32_t nIndex) {
+ if (IsValid(nIndex)) {
+ CFX_FloatRect rcItem = GetItemRectInternal(nIndex);
+ SetScrollPosY(rcItem.top);
+ }
+}
+
+int32_t CPWL_ListCtrl::GetTopItem() const {
+ int32_t nItemIndex = GetItemIndex(GetBTPoint());
+ if (!IsItemVisible(nItemIndex) && IsItemVisible(nItemIndex + 1))
+ nItemIndex += 1;
+
+ return nItemIndex;
+}
+
+void CPWL_ListCtrl::Empty() {
+ m_ListItems.clear();
+ InvalidateItem(-1);
+}
+
+void CPWL_ListCtrl::Cancel() {
+ m_aSelItems.DeselectAll();
+}
+
+int32_t CPWL_ListCtrl::GetItemIndex(const CFX_PointF& point) const {
+ CFX_PointF pt = OuterToInner(OutToIn(point));
+ bool bFirst = true;
+ bool bLast = true;
+ for (const auto& pListItem : m_ListItems) {
+ if (!pListItem)
+ continue;
+ CFX_FloatRect rcListItem = pListItem->GetRect();
+ if (IsFloatBigger(pt.y, rcListItem.top))
+ bFirst = false;
+ if (IsFloatSmaller(pt.y, rcListItem.bottom))
+ bLast = false;
+ if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom)
+ return &pListItem - &m_ListItems.front();
+ }
+ if (bFirst)
+ return 0;
+ if (bLast)
+ return pdfium::CollectionSize<int32_t>(m_ListItems) - 1;
+ return -1;
+}
+
+CFX_WideString CPWL_ListCtrl::GetText() const {
+ if (IsMultipleSel())
+ return GetItemText(m_nCaretIndex);
+ return GetItemText(m_nSelItem);
+}
+
+void CPWL_ListCtrl::AddItem(const CFX_WideString& str) {
+ auto pListItem = pdfium::MakeUnique<Item>();
+ pListItem->SetFontMap(m_pFontMap.Get());
+ pListItem->SetFontSize(m_fFontSize);
+ pListItem->SetText(str);
+ m_ListItems.push_back(std::move(pListItem));
+}
+
+CPWL_EditImpl* CPWL_ListCtrl::GetItemEdit(int32_t nIndex) const {
+ if (!pdfium::IndexInBounds(m_ListItems, nIndex) || !m_ListItems[nIndex])
+ return nullptr;
+ return m_ListItems[nIndex]->GetEdit();
+}
+
+int32_t CPWL_ListCtrl::GetCount() const {
+ return pdfium::CollectionSize<int32_t>(m_ListItems);
+}
+
+float CPWL_ListCtrl::GetFirstHeight() const {
+ if (m_ListItems.empty() || !m_ListItems.front())
+ return 1.0f;
+ return m_ListItems.front()->GetItemHeight();
+}
+
+int32_t CPWL_ListCtrl::GetFirstSelected() const {
+ int32_t i = 0;
+ for (const auto& pListItem : m_ListItems) {
+ if (pListItem && pListItem->IsSelected())
+ return i;
+ ++i;
+ }
+ return -1;
+}
+
+int32_t CPWL_ListCtrl::GetLastSelected() const {
+ for (auto iter = m_ListItems.rbegin(); iter != m_ListItems.rend(); ++iter) {
+ if (*iter && (*iter)->IsSelected())
+ return &*iter - &m_ListItems.front();
+ }
+ return -1;
+}
+
+int32_t CPWL_ListCtrl::FindNext(int32_t nIndex, wchar_t nChar) const {
+ int32_t nCircleIndex = nIndex;
+ int32_t sz = pdfium::CollectionSize<int32_t>(m_ListItems);
+ for (int32_t i = 0; i < sz; i++) {
+ nCircleIndex++;
+ if (nCircleIndex >= sz)
+ nCircleIndex = 0;
+
+ if (Item* pListItem = m_ListItems[nCircleIndex].get()) {
+ if (FXSYS_toupper(pListItem->GetFirstChar()) == FXSYS_toupper(nChar))
+ return nCircleIndex;
+ }
+ }
+
+ return nCircleIndex;
+}
+
+bool CPWL_ListCtrl::IsItemSelected(int32_t nIndex) const {
+ return pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex] &&
+ m_ListItems[nIndex]->IsSelected();
+}
+
+void CPWL_ListCtrl::SetItemSelect(int32_t nIndex, bool bSelected) {
+ if (pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex])
+ m_ListItems[nIndex]->SetSelect(bSelected);
+}
+
+bool CPWL_ListCtrl::IsValid(int32_t nItemIndex) const {
+ return pdfium::IndexInBounds(m_ListItems, nItemIndex);
+}
+
+CFX_WideString CPWL_ListCtrl::GetItemText(int32_t nIndex) const {
+ if (pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex])
+ return m_ListItems[nIndex]->GetText();
+ return L"";
+}