Allow external font-path configuration from pdfium_test.
[pdfium.git] / fpdfsdk / src / fxedit / fxet_list.cpp
index 63aee1b..70dc8d5 100644 (file)
 // 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 "../../include/fxedit/fxet_stub.h"
 #include "../../include/fxedit/fxet_edit.h"
 #include "../../include/fxedit/fxet_list.h"
 
-/* ------------------------------- CFX_ListItem ---------------------------------- */
+/* ------------------------------- CFX_ListItem
+ * ---------------------------------- */
 
-CFX_ListItem::CFX_ListItem() : m_pEdit(NULL),
-       m_bSelected(FALSE),
-       m_bCaret(FALSE),
-       m_rcListItem(0.0f,0.0f,0.0f,0.0f)
-{
-       m_pEdit = IFX_Edit::NewEdit();
-       ASSERT(m_pEdit != NULL);
+CFX_ListItem::CFX_ListItem()
+    : m_pEdit(NULL),
+      m_bSelected(FALSE),
+      m_bCaret(FALSE),
+      m_rcListItem(0.0f, 0.0f, 0.0f, 0.0f) {
+  m_pEdit = IFX_Edit::NewEdit();
+  ASSERT(m_pEdit != NULL);
 
-       m_pEdit->SetAlignmentV(1);
-       m_pEdit->Initialize();
+  m_pEdit->SetAlignmentV(1);
+  m_pEdit->Initialize();
 }
 
-CFX_ListItem::~CFX_ListItem()
-{
-       IFX_Edit::DelEdit(m_pEdit);
+CFX_ListItem::~CFX_ListItem() {
+  IFX_Edit::DelEdit(m_pEdit);
 }
 
-void CFX_ListItem::SetFontMap(IFX_Edit_FontMap * pFontMap)
-{
-       if (m_pEdit)
-               m_pEdit->SetFontMap(pFontMap);
+void CFX_ListItem::SetFontMap(IFX_Edit_FontMap* pFontMap) {
+  if (m_pEdit)
+    m_pEdit->SetFontMap(pFontMap);
 }
 
-IFX_Edit* CFX_ListItem::GetEdit() const
-{
-       return m_pEdit;
+IFX_Edit* CFX_ListItem::GetEdit() const {
+  return m_pEdit;
 }
 
-IFX_Edit_Iterator*     CFX_ListItem::GetIterator() const
-{
-       if (m_pEdit)
-               return m_pEdit->GetIterator();
+IFX_Edit_Iterator* CFX_ListItem::GetIterator() const {
+  if (m_pEdit)
+    return m_pEdit->GetIterator();
 
-       return NULL;
+  return NULL;
 }
 
-void CFX_ListItem::SetRect(const CLST_Rect & rect)
-{
-       m_rcListItem = rect;
+void CFX_ListItem::SetRect(const CLST_Rect& rect) {
+  m_rcListItem = rect;
 }
 
-CLST_Rect CFX_ListItem::GetRect() const
-{
-       return m_rcListItem;
+CLST_Rect CFX_ListItem::GetRect() const {
+  return m_rcListItem;
 }
 
-FX_BOOL CFX_ListItem::IsSelected() const
-{
-       return m_bSelected;
+FX_BOOL CFX_ListItem::IsSelected() const {
+  return m_bSelected;
 }
 
-void CFX_ListItem::SetSelect(FX_BOOL bSelected)
-{
-       m_bSelected = bSelected;
+void CFX_ListItem::SetSelect(FX_BOOL bSelected) {
+  m_bSelected = bSelected;
 }
 
-FX_BOOL CFX_ListItem::IsCaret() const
-{
-       return m_bCaret;
+FX_BOOL CFX_ListItem::IsCaret() const {
+  return m_bCaret;
 }
 
-void CFX_ListItem::SetCaret(FX_BOOL bCaret)
-{
-       m_bCaret = bCaret;
+void CFX_ListItem::SetCaret(FX_BOOL bCaret) {
+  m_bCaret = bCaret;
 }
 
-void CFX_ListItem::SetText(FX_LPCWSTR text)
-{
-       if (m_pEdit)
-               m_pEdit->SetText(text);
+void CFX_ListItem::SetText(const FX_WCHAR* text) {
+  if (m_pEdit)
+    m_pEdit->SetText(text);
 }
 
-void CFX_ListItem::SetFontSize(FX_FLOAT fFontSize)
-{
-       if (m_pEdit)
-               m_pEdit->SetFontSize(fFontSize);
+void CFX_ListItem::SetFontSize(FX_FLOAT fFontSize) {
+  if (m_pEdit)
+    m_pEdit->SetFontSize(fFontSize);
 }
 
-FX_FLOAT CFX_ListItem::GetItemHeight() const
-{
-       if (m_pEdit)
-               return m_pEdit->GetContentRect().Height();
+FX_FLOAT CFX_ListItem::GetItemHeight() const {
+  if (m_pEdit)
+    return m_pEdit->GetContentRect().Height();
 
-       return 0.0f;
+  return 0.0f;
 }
 
-FX_WORD CFX_ListItem::GetFirstChar() const
-{
-       CPVT_Word word;
+FX_WORD CFX_ListItem::GetFirstChar() const {
+  CPVT_Word word;
 
-       if (IFX_Edit_Iterator*  pIterator = GetIterator())
-       {
-               pIterator->SetAt(1);            
-               pIterator->GetWord(word);
-       }
+  if (IFX_Edit_Iterator* pIterator = GetIterator()) {
+    pIterator->SetAt(1);
+    pIterator->GetWord(word);
+  }
 
-       return word.Word;
+  return word.Word;
 }
 
-CFX_WideString CFX_ListItem::GetText() const
-{
-       if (m_pEdit)
-               return m_pEdit->GetText();
+CFX_WideString CFX_ListItem::GetText() const {
+  if (m_pEdit)
+    return m_pEdit->GetText();
 
-       return L"";
+  return L"";
 }
 
-/* ------------------------------------ CFX_List --------------------------------- */
+/* ------------------------------------ CFX_List
+ * --------------------------------- */
+
+CFX_List::CFX_List()
+    : m_fFontSize(0.0f), m_pFontMap(NULL), m_bMultiple(FALSE) {}
 
-CFX_List::CFX_List() : m_pFontMap(NULL), m_fFontSize(0.0f), m_bMultiple(FALSE) 
-{
+CFX_List::~CFX_List() {
+  Empty();
 }
 
-CFX_List::~CFX_List()
-{
-       Empty();
+void CFX_List::Empty() {
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++)
+    delete m_aListItems.GetAt(i);
+
+  m_aListItems.RemoveAll();
 }
 
-void CFX_List::Empty()
-{
-       for (FX_INT32 i=0,sz=m_aListItems.GetSize(); i<sz; i++)
-               delete m_aListItems.GetAt(i);
+void CFX_List::SetFontMap(IFX_Edit_FontMap* pFontMap) {
+  m_pFontMap = pFontMap;
+}
 
-       m_aListItems.RemoveAll();
+void CFX_List::SetFontSize(FX_FLOAT fFontSize) {
+  m_fFontSize = fFontSize;
 }
 
-void CFX_List::SetFontMap(IFX_Edit_FontMap * pFontMap)
-{
-       m_pFontMap = pFontMap;
+void CFX_List::AddItem(const FX_WCHAR* str) {
+  if (CFX_ListItem* pListItem = new CFX_ListItem()) {
+    pListItem->SetFontMap(m_pFontMap);
+    pListItem->SetFontSize(m_fFontSize);
+    pListItem->SetText(str);
+    m_aListItems.Add(pListItem);
+  }
 }
 
-void CFX_List::SetFontSize(FX_FLOAT fFontSize)
-{
-       m_fFontSize = fFontSize;
+void CFX_List::ReArrange(int32_t nItemIndex) {
+  FX_FLOAT fPosY = 0.0f;
+
+  if (CFX_ListItem* pPrevItem = m_aListItems.GetAt(nItemIndex - 1))
+    fPosY = pPrevItem->GetRect().bottom;
+
+  for (int32_t i = nItemIndex, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      FX_FLOAT fListItemHeight = pListItem->GetItemHeight();
+      pListItem->SetRect(CLST_Rect(0.0f, fPosY, 0.0f, fPosY + fListItemHeight));
+      fPosY += fListItemHeight;
+    }
+  }
+
+  SetContentRect(CLST_Rect(0.0f, 0.0f, 0.0f, fPosY));
 }
 
-void CFX_List::AddItem(FX_LPCWSTR str)
-{      
-       if (CFX_ListItem * pListItem = new CFX_ListItem())
-       {
-               pListItem->SetFontMap(m_pFontMap);
-               pListItem->SetFontSize(m_fFontSize);
-               pListItem->SetText(str);
-               m_aListItems.Add(pListItem);
-       }
+IFX_Edit* CFX_List::GetItemEdit(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    return pListItem->GetEdit();
+  }
+
+  return NULL;
 }
 
-void CFX_List::ReArrange(FX_INT32 nItemIndex)
-{
-       FX_FLOAT fPosY = 0.0f;
+int32_t CFX_List::GetCount() const {
+  return m_aListItems.GetSize();
+}
+
+CPDF_Rect CFX_List::GetPlateRect() const {
+  return CFX_ListContainer::GetPlateRect();
+}
 
-       if (CFX_ListItem * pPrevItem = m_aListItems.GetAt(nItemIndex - 1))
-               fPosY = pPrevItem->GetRect().bottom;
-       
-       for (FX_INT32 i=nItemIndex,sz=m_aListItems.GetSize(); i<sz; i++)
-       {
-               if (CFX_ListItem * pListItem = m_aListItems.GetAt(i))
-               {
-                       FX_FLOAT fListItemHeight = pListItem->GetItemHeight();
-                       pListItem->SetRect(CLST_Rect(0.0f,fPosY,0.0f,fPosY + fListItemHeight));
-                       fPosY += fListItemHeight;                       
-               }
-       }
+CPDF_Rect CFX_List::GetContentRect() const {
+  return InnerToOuter(CFX_ListContainer::GetContentRect());
+}
 
-       SetContentRect(CLST_Rect(0.0f,0.0f,0.0f,fPosY));        
+FX_FLOAT CFX_List::GetFontSize() const {
+  return m_fFontSize;
 }
 
-IFX_Edit * CFX_List::GetItemEdit(FX_INT32 nIndex) const
-{
-       if (CFX_ListItem * pListItem = m_aListItems.GetAt(nIndex))
-       {
-               return pListItem->GetEdit();
-       }
+int32_t CFX_List::GetItemIndex(const CPDF_Point& point) const {
+  CPDF_Point pt = OuterToInner(point);
+
+  FX_BOOL bFirst = TRUE;
+  FX_BOOL bLast = TRUE;
+
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      CLST_Rect rcListItem = pListItem->GetRect();
+
+      if (FX_EDIT_IsFloatBigger(pt.y, rcListItem.top)) {
+        bFirst = FALSE;
+      }
+
+      if (FX_EDIT_IsFloatSmaller(pt.y, rcListItem.bottom)) {
+        bLast = FALSE;
+      }
+
+      if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) {
+        return i;
+      }
+    }
+  }
 
-       return NULL;
+  if (bFirst)
+    return 0;
+  if (bLast)
+    return m_aListItems.GetSize() - 1;
+
+  return -1;
 }
 
-FX_INT32 CFX_List::GetCount() const
-{
-       return m_aListItems.GetSize();
+FX_FLOAT CFX_List::GetFirstHeight() const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(0)) {
+    return pListItem->GetItemHeight();
+  }
+
+  return 1.0f;
 }
 
-CPDF_Rect CFX_List::GetPlateRect() const
-{
-       return CFX_ListContainer::GetPlateRect();
+int32_t CFX_List::GetFirstSelected() const {
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      if (pListItem->IsSelected())
+        return i;
+    }
+  }
+  return -1;
 }
 
-CPDF_Rect CFX_List::GetContentRect() const
-{
-       return InnerToOuter(CFX_ListContainer::GetContentRect());
+int32_t CFX_List::GetLastSelected() const {
+  for (int32_t i = m_aListItems.GetSize() - 1; i >= 0; i--) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      if (pListItem->IsSelected())
+        return i;
+    }
+  }
+  return -1;
 }
 
-FX_FLOAT CFX_List::GetFontSize() const
-{
-       return m_fFontSize;
+FX_WCHAR CFX_List::Toupper(FX_WCHAR c) const {
+  if ((c >= 'a') && (c <= 'z'))
+    c = c - ('a' - 'A');
+  return c;
 }
 
-FX_INT32 CFX_List::GetItemIndex(const CPDF_Point & point) const
-{
-       CPDF_Point pt = OuterToInner(point);
+int32_t CFX_List::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
+  int32_t nCircleIndex = nIndex;
+
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    nCircleIndex++;
+    if (nCircleIndex >= sz)
+      nCircleIndex = 0;
 
-       FX_BOOL bFirst = TRUE;
-       FX_BOOL bLast = TRUE;
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(nCircleIndex)) {
+      if (Toupper(pListItem->GetFirstChar()) == Toupper(nChar))
+        return nCircleIndex;
+    }
+  }
+
+  return nCircleIndex;
+}
 
-       for (FX_INT32 i=0,sz=m_aListItems.GetSize(); i<sz; i++)
-       {
-               if (CFX_ListItem * pListItem = m_aListItems.GetAt(i))
-               {
-                       CLST_Rect rcListItem = pListItem->GetRect();
+CPDF_Rect CFX_List::GetItemRect(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    CPDF_Rect rcItem = pListItem->GetRect();
+    rcItem.left = 0.0f;
+    rcItem.right = GetPlateRect().Width();
+    return InnerToOuter(rcItem);
+  }
 
-                       if (FX_EDIT_IsFloatBigger(pt.y, rcListItem.top))
-                       {                       
-                               bFirst = FALSE;
-                       }
+  return CPDF_Rect();
+}
 
-                       if (FX_EDIT_IsFloatSmaller(pt.y, rcListItem.bottom))
-                       {
-                               bLast = FALSE;
-                       }
+FX_BOOL CFX_List::IsItemSelected(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    return pListItem->IsSelected();
+  }
 
-                       if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom)
-                       {
-                               return i;
-                       }
-               }
-       }
+  return FALSE;
+}
 
-       if (bFirst) return 0;
-       if (bLast) return m_aListItems.GetSize()-1;
+void CFX_List::SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected) {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
+    pListItem->SetSelect(bSelected);
+  }
+}
 
-       return -1;
+void CFX_List::SetItemCaret(int32_t nItemIndex, FX_BOOL bCaret) {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
+    pListItem->SetCaret(bCaret);
+  }
 }
 
-FX_FLOAT CFX_List::GetFirstHeight() const
-{
-       if (CFX_ListItem * pListItem = m_aListItems.GetAt(0))
-       {
-               return pListItem->GetItemHeight();
-       }
+void CFX_List::SetMultipleSel(FX_BOOL bMultiple) {
+  m_bMultiple = bMultiple;
+}
 
-       return 1.0f;
+FX_BOOL CFX_List::IsMultipleSel() const {
+  return m_bMultiple;
 }
 
-FX_INT32 CFX_List::GetFirstSelected() const
-{
-       for (FX_INT32 i=0,sz=m_aListItems.GetSize(); i<sz; i++)
-       {
-               if (CFX_ListItem * pListItem = m_aListItems.GetAt(i))
-               {
-                       if (pListItem->IsSelected())
-                               return i;
-               }
-       }
-       return -1;
+FX_BOOL CFX_List::IsValid(int32_t nItemIndex) const {
+  return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize();
 }
 
-FX_INT32 CFX_List::GetLastSelected() const
-{
-       for (FX_INT32 i=m_aListItems.GetSize()-1; i>=0; i--)
-       {
-               if (CFX_ListItem * pListItem = m_aListItems.GetAt(i))
-               {
-                       if (pListItem->IsSelected())
-                               return i;
-               }
-       }
-       return -1;
+CFX_WideString CFX_List::GetItemText(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    return pListItem->GetText();
+  }
+
+  return L"";
 }
 
-FX_WCHAR CFX_List::Toupper(FX_WCHAR c) const
-{
-       if ( (c >= 'a') && (c <= 'z') )
-               c = c - ('a' - 'A');
-       return c;
+/* ------------------------------------ CPLST_Select
+ * ---------------------------------- */
+
+CPLST_Select::CPLST_Select() {}
+
+CPLST_Select::~CPLST_Select() {
+  for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++)
+    delete m_aItems.GetAt(i);
+
+  m_aItems.RemoveAll();
 }
 
-FX_INT32 CFX_List::FindNext(FX_INT32 nIndex,FX_WCHAR nChar) const
-{
-       FX_INT32 nCircleIndex = nIndex;
+void CPLST_Select::Add(int32_t nItemIndex) {
+  int32_t nIndex = Find(nItemIndex);
 
-       for (FX_INT32 i=0,sz=m_aListItems.GetSize(); i<sz; i++)
-       {
-               nCircleIndex ++;
-               if (nCircleIndex >= sz) nCircleIndex = 0;
+  if (nIndex < 0)
+    m_aItems.Add(new CPLST_Select_Item(nItemIndex, 1));
+  else {
+    if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex)) {
+      pItem->nState = 1;
+    }
+  }
+}
 
-               if (CFX_ListItem * pListItem = m_aListItems.GetAt(nCircleIndex))
-               {
-                       if (Toupper(pListItem->GetFirstChar()) == Toupper(nChar))
-                               return nCircleIndex;
-               }
-       }
+void CPLST_Select::Add(int32_t nBeginIndex, int32_t nEndIndex) {
+  if (nBeginIndex > nEndIndex) {
+    int32_t nTemp = nEndIndex;
+    nEndIndex = nBeginIndex;
+    nBeginIndex = nTemp;
+  }
+
+  for (int32_t i = nBeginIndex; i <= nEndIndex; i++)
+    Add(i);
+}
 
-       return nCircleIndex;
+void CPLST_Select::Sub(int32_t nItemIndex) {
+  for (int32_t i = m_aItems.GetSize() - 1; i >= 0; i--) {
+    if (CPLST_Select_Item* pItem = m_aItems.GetAt(i))
+      if (pItem->nItemIndex == nItemIndex)
+        pItem->nState = -1;
+  }
 }
 
-CPDF_Rect CFX_List::GetItemRect(FX_INT32 nIndex) const
-{
-       if (CFX_ListItem * pListItem = m_aListItems.GetAt(nIndex))
-       {
-               CPDF_Rect rcItem = pListItem->GetRect();
-               rcItem.left = 0.0f;
-               rcItem.right = GetPlateRect().Width();
-               return InnerToOuter(rcItem);
-       }
+void CPLST_Select::Sub(int32_t nBeginIndex, int32_t nEndIndex) {
+  if (nBeginIndex > nEndIndex) {
+    int32_t nTemp = nEndIndex;
+    nEndIndex = nBeginIndex;
+    nBeginIndex = nTemp;
+  }
 
-       return CPDF_Rect();
+  for (int32_t i = nBeginIndex; i <= nEndIndex; i++)
+    Sub(i);
 }
 
-FX_BOOL CFX_List::IsItemSelected(FX_INT32 nIndex) const
-{
-       if (CFX_ListItem * pListItem = m_aListItems.GetAt(nIndex))
-       {
-               return pListItem->IsSelected();
-       }
+int32_t CPLST_Select::Find(int32_t nItemIndex) const {
+  for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++) {
+    if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
+      if (pItem->nItemIndex == nItemIndex)
+        return i;
+    }
+  }
 
-       return FALSE;
+  return -1;
 }
 
-void CFX_List::SetItemSelect(FX_INT32 nItemIndex, FX_BOOL bSelected)
-{
-       if (CFX_ListItem * pListItem = m_aListItems.GetAt(nItemIndex))
-       {
-               pListItem->SetSelect(bSelected);
-       }
+FX_BOOL CPLST_Select::IsExist(int32_t nItemIndex) const {
+  return Find(nItemIndex) >= 0;
 }
 
-void CFX_List::SetItemCaret(FX_INT32 nItemIndex, FX_BOOL bCaret)
-{
-       if (CFX_ListItem * pListItem = m_aListItems.GetAt(nItemIndex))
-       {
-               pListItem->SetCaret(bCaret);            
-       }
+int32_t CPLST_Select::GetCount() const {
+  return m_aItems.GetSize();
 }
 
-void CFX_List::SetMultipleSel(FX_BOOL bMultiple)
-{
-       m_bMultiple = bMultiple;
+int32_t CPLST_Select::GetItemIndex(int32_t nIndex) const {
+  if (nIndex >= 0 && nIndex < m_aItems.GetSize())
+    if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex))
+      return pItem->nItemIndex;
+
+  return -1;
+}
+
+int32_t CPLST_Select::GetState(int32_t nIndex) const {
+  if (nIndex >= 0 && nIndex < m_aItems.GetSize())
+    if (CPLST_Select_Item* pItem = m_aItems.GetAt(nIndex))
+      return pItem->nState;
+
+  return 0;
 }
 
-FX_BOOL CFX_List::IsMultipleSel() const
-{
-       return m_bMultiple;
+void CPLST_Select::DeselectAll() {
+  for (int32_t i = 0, sz = m_aItems.GetSize(); i < sz; i++) {
+    if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
+      pItem->nState = -1;
+    }
+  }
 }
 
-FX_BOOL CFX_List::IsValid(FX_INT32 nItemIndex) const
-{
-       return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize();
+void CPLST_Select::Done() {
+  for (int32_t i = m_aItems.GetSize() - 1; i >= 0; i--) {
+    if (CPLST_Select_Item* pItem = m_aItems.GetAt(i)) {
+      if (pItem->nState == -1) {
+        delete pItem;
+        m_aItems.RemoveAt(i);
+      } else {
+        pItem->nState = 0;
+      }
+    }
+  }
 }
 
-CFX_WideString CFX_List::GetItemText(FX_INT32 nIndex) const
-{
-       if (CFX_ListItem * pListItem = m_aListItems.GetAt(nIndex))
-       {
-               return pListItem->GetText();
-       }
+/* ------------------------------------ CFX_ListCtrl
+ * --------------------------------- */
+
+CFX_ListCtrl::CFX_ListCtrl()
+    : m_pNotify(NULL),
+      m_bNotifyFlag(FALSE),
+      m_ptScrollPos(0.0f, 0.0f),
+      m_nSelItem(-1),
+      m_nFootIndex(-1),
+      m_bCtrlSel(FALSE),
+      m_nCaretIndex(-1) {}
+
+CFX_ListCtrl::~CFX_ListCtrl() {}
 
-       return L"";
+void CFX_ListCtrl::SetNotify(IFX_List_Notify* pNotify) {
+  m_pNotify = pNotify;
 }
 
-/* ------------------------------------ CPLST_Select ---------------------------------- */
+CPDF_Point CFX_ListCtrl::InToOut(const CPDF_Point& point) const {
+  CPDF_Rect rcPlate = GetPlateRect();
 
-CPLST_Select::CPLST_Select()
-{
+  return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
+                    point.y - (m_ptScrollPos.y - rcPlate.top));
 }
 
-CPLST_Select::~CPLST_Select()
-{
-       for (FX_INT32 i=0,sz=m_aItems.GetSize(); i<sz; i++)
-               delete m_aItems.GetAt(i);
+CPDF_Point CFX_ListCtrl::OutToIn(const CPDF_Point& point) const {
+  CPDF_Rect rcPlate = GetPlateRect();
 
-       m_aItems.RemoveAll();
+  return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
+                    point.y + (m_ptScrollPos.y - rcPlate.top));
 }
 
-void CPLST_Select::Add(FX_INT32 nItemIndex)
-{
-       FX_INT32 nIndex = Find(nItemIndex);
+CPDF_Rect CFX_ListCtrl::InToOut(const CPDF_Rect& rect) const {
+  CPDF_Point ptLeftBottom = InToOut(CPDF_Point(rect.left, rect.bottom));
+  CPDF_Point ptRightTop = InToOut(CPDF_Point(rect.right, rect.top));
 
-       if (nIndex < 0) 
-               m_aItems.Add(new CPLST_Select_Item(nItemIndex,1));
-       else
-       {
-               if (CPLST_Select_Item * pItem = m_aItems.GetAt(nIndex))
-               {
-                       pItem->nState = 1;
-               }
-       }
+  return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y);
 }
 
-void CPLST_Select::Add(FX_INT32 nBeginIndex, FX_INT32 nEndIndex)
-{
-       if (nBeginIndex > nEndIndex)
-       {
-               FX_INT32 nTemp = nEndIndex;
-               nEndIndex = nBeginIndex;
-               nBeginIndex = nTemp;
-       }
+CPDF_Rect CFX_ListCtrl::OutToIn(const CPDF_Rect& rect) const {
+  CPDF_Point ptLeftBottom = OutToIn(CPDF_Point(rect.left, rect.bottom));
+  CPDF_Point ptRightTop = OutToIn(CPDF_Point(rect.right, rect.top));
 
-       for (FX_INT32 i=nBeginIndex; i<=nEndIndex; i++) Add(i);
+  return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y);
 }
 
-void CPLST_Select::Sub(FX_INT32 nItemIndex)
-{
-       for (FX_INT32 i=m_aItems.GetSize()-1; i>=0; i--)
-       {
-               if (CPLST_Select_Item * pItem = m_aItems.GetAt(i))
-                       if (pItem->nItemIndex == nItemIndex)
-                               pItem->nState = -1;
-       }
+void CFX_ListCtrl::OnMouseDown(const CPDF_Point& point,
+                               FX_BOOL bShift,
+                               FX_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 CPLST_Select::Sub(FX_INT32 nBeginIndex, FX_INT32 nEndIndex)
-{
-       if (nBeginIndex > nEndIndex)
-       {
-               FX_INT32 nTemp = nEndIndex;
-               nEndIndex = nBeginIndex;
-               nBeginIndex = nTemp;
-       }
+void CFX_ListCtrl::OnMouseMove(const CPDF_Point& point,
+                               FX_BOOL bShift,
+                               FX_BOOL bCtrl) {
+  int32_t nHitIndex = GetItemIndex(point);
 
-       for (FX_INT32 i=nBeginIndex; i<=nEndIndex; i++) Sub(i);
+  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);
 }
 
-FX_INT32 CPLST_Select::Find(FX_INT32 nItemIndex) const
-{
-       for (FX_INT32 i=0,sz=m_aItems.GetSize(); i<sz; i++)
-       {
-               if (CPLST_Select_Item * pItem = m_aItems.GetAt(i))
-               {
-                       if (pItem->nItemIndex == nItemIndex)
-                               return i;
-               }
-       }
+void CFX_ListCtrl::OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_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;
+      }
 
-       return -1;
+      SetCaret(nItemIndex);
+    }
+  } else {
+    SetSingleSelect(nItemIndex);
+  }
+
+  if (!IsItemVisible(nItemIndex))
+    ScrollToListItem(nItemIndex);
 }
 
-FX_BOOL CPLST_Select::IsExist(FX_INT32 nItemIndex) const
-{
-       return Find(nItemIndex) >= 0;
+void CFX_ListCtrl::OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) {
+  OnVK(IsMultipleSel() ? GetCaret() - 1 : GetSelect() - 1, bShift, bCtrl);
 }
 
-FX_INT32 CPLST_Select::GetCount() const
-{
-       return m_aItems.GetSize();
+void CFX_ListCtrl::OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) {
+  OnVK(IsMultipleSel() ? GetCaret() + 1 : GetSelect() + 1, bShift, bCtrl);
 }
 
-FX_INT32 CPLST_Select::GetItemIndex(FX_INT32 nIndex) const
-{
-       if (nIndex >= 0 && nIndex < m_aItems.GetSize())
-               if (CPLST_Select_Item * pItem = m_aItems.GetAt(nIndex))
-                       return pItem->nItemIndex;
+void CFX_ListCtrl::OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) {
+  OnVK(0, bShift, bCtrl);
+}
 
-       return -1;
+void CFX_ListCtrl::OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) {
+  OnVK(GetCount() - 1, bShift, bCtrl);
 }
 
-FX_INT32 CPLST_Select::GetState(FX_INT32 nIndex) const
-{
-       if (nIndex >= 0 && nIndex < m_aItems.GetSize())
-               if (CPLST_Select_Item * pItem = m_aItems.GetAt(nIndex))
-                       return pItem->nState;
+void CFX_ListCtrl::OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) {
+  OnVK(0, bShift, bCtrl);
+}
 
-       return 0;
+void CFX_ListCtrl::OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) {
+  OnVK(GetCount() - 1, bShift, bCtrl);
 }
 
-void CPLST_Select::DeselectAll()
-{
-       for (FX_INT32 i=0,sz=m_aItems.GetSize(); i<sz; i++)
-       {
-               if (CPLST_Select_Item * pItem = m_aItems.GetAt(i))
-               {
-                       pItem->nState = -1;
-               }
-       }
-}
-
-void CPLST_Select::Done()
-{
-       for (FX_INT32 i=m_aItems.GetSize()-1; i>=0; i--)
-       {       
-               if (CPLST_Select_Item * pItem = m_aItems.GetAt(i))
-               {
-                       if (pItem->nState == -1)
-                       {
-                               delete pItem;
-                               m_aItems.RemoveAt(i);
-                       }
-                       else
-                       {
-                               pItem->nState = 0;
-                       }
-               }
-       }
-}
-
-/* ------------------------------------ CFX_ListCtrl --------------------------------- */
+FX_BOOL CFX_ListCtrl::OnChar(FX_WORD nChar, FX_BOOL bShift, FX_BOOL bCtrl) {
+  int32_t nIndex = GetLastSelected();
+  int32_t nFindIndex = FindNext(nIndex, nChar);
 
-CFX_ListCtrl::CFX_ListCtrl() : m_pNotify(NULL),
-       m_ptScrollPos(0.0f,0.0f),
-       m_nSelItem(-1),
-       m_nFootIndex(-1),
-       m_bCtrlSel(FALSE),      
-       m_nCaretIndex(-1),
-       m_bNotifyFlag(FALSE)
-{
-}
-
-CFX_ListCtrl::~CFX_ListCtrl()
-{
-}
-
-void CFX_ListCtrl::SetNotify(IFX_List_Notify * pNotify)
-{
-       m_pNotify = pNotify;
-}
-
-CPDF_Point CFX_ListCtrl::InToOut(const CPDF_Point & point) const
-{
-       CPDF_Rect rcPlate = GetPlateRect();
-
-       return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
-               point.y - (m_ptScrollPos.y - rcPlate.top));
-}
-
-CPDF_Point CFX_ListCtrl::OutToIn(const CPDF_Point & point) const
-{
-       CPDF_Rect rcPlate = GetPlateRect();
-
-       return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
-               point.y + (m_ptScrollPos.y - rcPlate.top));
-}
-
-CPDF_Rect CFX_ListCtrl::InToOut(const CPDF_Rect & rect) const
-{
-       CPDF_Point ptLeftBottom = InToOut(CPDF_Point(rect.left,rect.bottom));
-       CPDF_Point ptRightTop = InToOut(CPDF_Point(rect.right,rect.top));
-
-       return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
-}
-
-CPDF_Rect CFX_ListCtrl::OutToIn(const CPDF_Rect & rect) const
-{
-       CPDF_Point ptLeftBottom = OutToIn(CPDF_Point(rect.left,rect.bottom));
-       CPDF_Point ptRightTop = OutToIn(CPDF_Point(rect.right,rect.top));
-
-       return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
-}
-
-void CFX_ListCtrl::OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       FX_INT32 nHitIndex = this->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 (!this->IsItemVisible(nHitIndex))
-               this->ScrollToListItem(nHitIndex);
-}
-
-void CFX_ListCtrl::OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       FX_INT32 nHitIndex = this->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 (!this->IsItemVisible(nHitIndex))
-               this->ScrollToListItem(nHitIndex);
-}
-
-void CFX_ListCtrl::OnVK(FX_INT32 nItemIndex,FX_BOOL bShift,FX_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 (!this->IsItemVisible(nItemIndex))
-               this->ScrollToListItem(nItemIndex);
-}
-
-void CFX_ListCtrl::OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       OnVK(IsMultipleSel() ? GetCaret()-1 : GetSelect()-1, bShift, bCtrl);
-}
-
-void CFX_ListCtrl::OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       OnVK(IsMultipleSel() ? GetCaret()+1 : GetSelect()+1, bShift, bCtrl);
-}
-
-void CFX_ListCtrl::OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       OnVK(0, bShift, bCtrl);
-}
-
-void CFX_ListCtrl::OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       OnVK(GetCount()-1, bShift, bCtrl);
-}
-
-void CFX_ListCtrl::OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       OnVK(0, bShift, bCtrl);
-}
-
-void CFX_ListCtrl::OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       OnVK(GetCount()-1, bShift, bCtrl);
-}
-
-FX_BOOL        CFX_ListCtrl::OnChar(FX_WORD nChar,FX_BOOL bShift,FX_BOOL bCtrl)
-{
-       FX_INT32 nIndex = GetLastSelected();    
-       FX_INT32 nFindIndex = FindNext(nIndex,nChar);
-
-       if (nFindIndex != nIndex)
-       {
-               OnVK(nFindIndex, bShift, bCtrl);
-               return TRUE;
-       }
-       return FALSE;
+  if (nFindIndex != nIndex) {
+    OnVK(nFindIndex, bShift, bCtrl);
+    return TRUE;
+  }
+  return FALSE;
 }
 
 /* -------- inner methods ------- */
 
-void CFX_ListCtrl::SetPlateRect(const CPDF_Rect & rect)
-{
-       CFX_ListContainer::SetPlateRect(rect);
-       m_ptScrollPos.x = rect.left;
-       SetScrollPos(CPDF_Point(rect.left,rect.top));   
-       ReArrange(0);
-       InvalidateItem(-1);
-}
-
-CPDF_Rect CFX_ListCtrl::GetItemRect(FX_INT32 nIndex) const
-{
-       return InToOut(CFX_List::GetItemRect(nIndex));
-}
-
-void CFX_ListCtrl::AddString(FX_LPCWSTR string)
-{
-       AddItem(string);
-       ReArrange(GetCount() - 1);
-}
-
-void CFX_ListCtrl::SetMultipleSelect(FX_INT32 nItemIndex, FX_BOOL bSelected)
-{
-       if (!IsValid(nItemIndex)) return;
-
-       if (bSelected != this->IsItemSelected(nItemIndex))
-       {
-               if (bSelected)
-               {
-                       SetItemSelect(nItemIndex,TRUE);
-                       InvalidateItem(nItemIndex);
-               }
-               else
-               {
-                       SetItemSelect(nItemIndex,FALSE);
-                       InvalidateItem(nItemIndex);
-               }
-       }
-}
-
-void CFX_ListCtrl::SetSingleSelect(FX_INT32 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 CFX_ListCtrl::SetCaret(FX_INT32 nItemIndex)
-{
-       if (!IsValid(nItemIndex)) return;
-
-       if (this->IsMultipleSel())
-       {               
-               FX_INT32 nOldIndex = m_nCaretIndex;
-
-               if (nOldIndex != nItemIndex)
-               {
-                       m_nCaretIndex = nItemIndex;
-
-                       SetItemCaret(nOldIndex, FALSE);
-                       SetItemCaret(nItemIndex,TRUE);
-
-                       InvalidateItem(nOldIndex);
-                       InvalidateItem(nItemIndex);                     
-               }
-       }
-}
-
-void CFX_ListCtrl::InvalidateItem(FX_INT32 nItemIndex)
-{
-       if (m_pNotify)
-       {
-               if (nItemIndex == -1)
-               {
-                       if (!m_bNotifyFlag)
-                       {
-                               m_bNotifyFlag = TRUE;
-                               CPDF_Rect rcRefresh = GetPlateRect();
-                               m_pNotify->IOnInvalidateRect(&rcRefresh);
-                               m_bNotifyFlag = FALSE;
-                       }
-               }
-               else
-               {
-                       if (!m_bNotifyFlag)
-                       {
-                               m_bNotifyFlag = TRUE;
-                               CPDF_Rect 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 CFX_ListCtrl::SelectItems()
-{
-       for (FX_INT32 i=0,sz=m_aSelItems.GetCount(); i<sz; i++)
-       {
-               FX_INT32 nItemIndex = m_aSelItems.GetItemIndex(i);
-               FX_INT32 nState = m_aSelItems.GetState(i);
-
-               switch(nState)
-               {
-               case 1:
-                       SetMultipleSelect(nItemIndex, TRUE);                    
-                       break;
-               case -1:
-                       SetMultipleSelect(nItemIndex, FALSE);
-                       break;
-               }
-       }
-
-       m_aSelItems.Done();
-}
-
-void CFX_ListCtrl::Select(FX_INT32 nItemIndex)
-{
-       if (!IsValid(nItemIndex)) return;
-
-       if (this->IsMultipleSel())
-       {
-               m_aSelItems.Add(nItemIndex);
-               SelectItems();
-       }
-       else
-               SetSingleSelect(nItemIndex);
-}
-
-FX_BOOL        CFX_ListCtrl::IsItemVisible(FX_INT32 nItemIndex) const
-{
-       CPDF_Rect rcPlate = this->GetPlateRect();
-       CPDF_Rect rcItem = this->GetItemRect(nItemIndex);
-
-       return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top;
-}
-
-void CFX_ListCtrl::ScrollToListItem(FX_INT32 nItemIndex)
-{
-       if (!IsValid(nItemIndex)) return;
-
-       CPDF_Rect rcPlate = this->GetPlateRect();
-       CPDF_Rect rcItem = CFX_List::GetItemRect(nItemIndex);
-       CPDF_Rect rcItemCtrl = GetItemRect(nItemIndex);
-
-       if (FX_EDIT_IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom))
-       {
-               if (FX_EDIT_IsFloatSmaller(rcItemCtrl.top, rcPlate.top))
-               {
-                       SetScrollPosY(rcItem.bottom + rcPlate.Height());
-               }
-       }
-       else if (FX_EDIT_IsFloatBigger(rcItemCtrl.top, rcPlate.top))
-       {
-               if (FX_EDIT_IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom))
-               {
-                       SetScrollPosY(rcItem.top);
-               }
-       }
-}
-
-void CFX_ListCtrl::SetScrollInfo()
-{
-       if (m_pNotify)
-       {
-               CPDF_Rect rcPlate = GetPlateRect();
-               CPDF_Rect rcContent = CFX_List::GetContentRect();
-
-               if (!m_bNotifyFlag)
-               {
-                       m_bNotifyFlag = TRUE;
-                       m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top, 
-                                       rcContent.bottom, rcContent.top, GetFirstHeight(), rcPlate.Height());
-                       m_bNotifyFlag = FALSE;
-               }
-       }
-}
-
-void CFX_ListCtrl::SetScrollPos(const CPDF_Point & point)
-{
-       SetScrollPosY(point.y);
-}
-
-void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy)
-{
-       if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y,fy))
-       {
-               CPDF_Rect rcPlate = this->GetPlateRect();
-               CPDF_Rect rcContent = CFX_List::GetContentRect();
-
-               if (rcPlate.Height() > rcContent.Height())
-               {
-                       fy = rcPlate.top;
-               }
-               else
-               {
-                       if (FX_EDIT_IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom))
-                       {
-                               fy = rcContent.bottom + rcPlate.Height();
-                       }
-                       else if (FX_EDIT_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;
-                       }
-               }
-       }
-}
-
-CPDF_Rect CFX_ListCtrl::GetContentRect() const
-{
-       return InToOut(CFX_List::GetContentRect());
-}
+void CFX_ListCtrl::SetPlateRect(const CPDF_Rect& rect) {
+  CFX_ListContainer::SetPlateRect(rect);
+  m_ptScrollPos.x = rect.left;
+  SetScrollPos(CPDF_Point(rect.left, rect.top));
+  ReArrange(0);
+  InvalidateItem(-1);
+}
+
+CPDF_Rect CFX_ListCtrl::GetItemRect(int32_t nIndex) const {
+  return InToOut(CFX_List::GetItemRect(nIndex));
+}
+
+void CFX_ListCtrl::AddString(const FX_WCHAR* string) {
+  AddItem(string);
+  ReArrange(GetCount() - 1);
+}
+
+void CFX_ListCtrl::SetMultipleSelect(int32_t nItemIndex, FX_BOOL bSelected) {
+  if (!IsValid(nItemIndex))
+    return;
+
+  if (bSelected != IsItemSelected(nItemIndex)) {
+    if (bSelected) {
+      SetItemSelect(nItemIndex, TRUE);
+      InvalidateItem(nItemIndex);
+    } else {
+      SetItemSelect(nItemIndex, FALSE);
+      InvalidateItem(nItemIndex);
+    }
+  }
+}
+
+void CFX_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 CFX_ListCtrl::SetCaret(int32_t nItemIndex) {
+  if (!IsValid(nItemIndex))
+    return;
+
+  if (IsMultipleSel()) {
+    int32_t nOldIndex = m_nCaretIndex;
+
+    if (nOldIndex != nItemIndex) {
+      m_nCaretIndex = nItemIndex;
+
+      SetItemCaret(nOldIndex, FALSE);
+      SetItemCaret(nItemIndex, TRUE);
+
+      InvalidateItem(nOldIndex);
+      InvalidateItem(nItemIndex);
+    }
+  }
+}
+
+void CFX_ListCtrl::InvalidateItem(int32_t nItemIndex) {
+  if (m_pNotify) {
+    if (nItemIndex == -1) {
+      if (!m_bNotifyFlag) {
+        m_bNotifyFlag = TRUE;
+        CPDF_Rect rcRefresh = GetPlateRect();
+        m_pNotify->IOnInvalidateRect(&rcRefresh);
+        m_bNotifyFlag = FALSE;
+      }
+    } else {
+      if (!m_bNotifyFlag) {
+        m_bNotifyFlag = TRUE;
+        CPDF_Rect 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 CFX_ListCtrl::SelectItems() {
+  for (int32_t i = 0, sz = m_aSelItems.GetCount(); i < sz; i++) {
+    int32_t nItemIndex = m_aSelItems.GetItemIndex(i);
+    int32_t nState = m_aSelItems.GetState(i);
+
+    switch (nState) {
+      case 1:
+        SetMultipleSelect(nItemIndex, TRUE);
+        break;
+      case -1:
+        SetMultipleSelect(nItemIndex, FALSE);
+        break;
+    }
+  }
+
+  m_aSelItems.Done();
+}
+
+void CFX_ListCtrl::Select(int32_t nItemIndex) {
+  if (!IsValid(nItemIndex))
+    return;
+
+  if (IsMultipleSel()) {
+    m_aSelItems.Add(nItemIndex);
+    SelectItems();
+  } else
+    SetSingleSelect(nItemIndex);
+}
+
+FX_BOOL CFX_ListCtrl::IsItemVisible(int32_t nItemIndex) const {
+  CPDF_Rect rcPlate = GetPlateRect();
+  CPDF_Rect rcItem = GetItemRect(nItemIndex);
+
+  return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top;
+}
+
+void CFX_ListCtrl::ScrollToListItem(int32_t nItemIndex) {
+  if (!IsValid(nItemIndex))
+    return;
 
-void CFX_ListCtrl::ReArrange(FX_INT32 nItemIndex)
-{
-       CFX_List::ReArrange(nItemIndex);
-       SetScrollInfo();
-}
-
-void CFX_ListCtrl::SetTopItem(FX_INT32 nIndex)
-{
-       if (IsValid(nIndex))
-       {
-               this->GetPlateRect();
-               CPDF_Rect rcItem = CFX_List::GetItemRect(nIndex);
-               SetScrollPosY(rcItem.top);
-       }
-}
-
-FX_INT32 CFX_ListCtrl::GetTopItem() const
-{
-       FX_INT32 nItemIndex = this->GetItemIndex(this->GetBTPoint());
-
-       if (!IsItemVisible(nItemIndex) && IsItemVisible(nItemIndex + 1))
-                       nItemIndex += 1;
-
-       return nItemIndex;
-}
-
-void CFX_ListCtrl::Empty()
-{
-       CFX_List::Empty();
-       InvalidateItem(-1);
+  CPDF_Rect rcPlate = GetPlateRect();
+  CPDF_Rect rcItem = CFX_List::GetItemRect(nItemIndex);
+  CPDF_Rect rcItemCtrl = GetItemRect(nItemIndex);
+
+  if (FX_EDIT_IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
+    if (FX_EDIT_IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
+      SetScrollPosY(rcItem.bottom + rcPlate.Height());
+    }
+  } else if (FX_EDIT_IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
+    if (FX_EDIT_IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
+      SetScrollPosY(rcItem.top);
+    }
+  }
+}
+
+void CFX_ListCtrl::SetScrollInfo() {
+  if (m_pNotify) {
+    CPDF_Rect rcPlate = GetPlateRect();
+    CPDF_Rect rcContent = CFX_List::GetContentRect();
+
+    if (!m_bNotifyFlag) {
+      m_bNotifyFlag = TRUE;
+      m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
+                                   rcContent.bottom, rcContent.top,
+                                   GetFirstHeight(), rcPlate.Height());
+      m_bNotifyFlag = FALSE;
+    }
+  }
+}
+
+void CFX_ListCtrl::SetScrollPos(const CPDF_Point& point) {
+  SetScrollPosY(point.y);
+}
+
+void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy) {
+  if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y, fy)) {
+    CPDF_Rect rcPlate = GetPlateRect();
+    CPDF_Rect rcContent = CFX_List::GetContentRect();
+
+    if (rcPlate.Height() > rcContent.Height()) {
+      fy = rcPlate.top;
+    } else {
+      if (FX_EDIT_IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
+        fy = rcContent.bottom + rcPlate.Height();
+      } else if (FX_EDIT_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;
+      }
+    }
+  }
 }
 
-void CFX_ListCtrl::Cancel()
-{
-       m_aSelItems.DeselectAll();
+CPDF_Rect CFX_ListCtrl::GetContentRect() const {
+  return InToOut(CFX_List::GetContentRect());
 }
 
-FX_INT32 CFX_ListCtrl::GetItemIndex(const CPDF_Point & point) const
-{
-       return CFX_List::GetItemIndex(OutToIn(point));
+void CFX_ListCtrl::ReArrange(int32_t nItemIndex) {
+  CFX_List::ReArrange(nItemIndex);
+  SetScrollInfo();
 }
 
-CFX_WideString CFX_ListCtrl::GetText() const
-{
-       if (this->IsMultipleSel())
-               return this->GetItemText(this->m_nCaretIndex);  
-       else
-               return this->GetItemText(this->m_nSelItem);
+void CFX_ListCtrl::SetTopItem(int32_t nIndex) {
+  if (IsValid(nIndex)) {
+    GetPlateRect();
+    CPDF_Rect rcItem = CFX_List::GetItemRect(nIndex);
+    SetScrollPosY(rcItem.top);
+  }
 }
 
+int32_t CFX_ListCtrl::GetTopItem() const {
+  int32_t nItemIndex = GetItemIndex(GetBTPoint());
+
+  if (!IsItemVisible(nItemIndex) && IsItemVisible(nItemIndex + 1))
+    nItemIndex += 1;
+
+  return nItemIndex;
+}
+
+void CFX_ListCtrl::Empty() {
+  CFX_List::Empty();
+  InvalidateItem(-1);
+}
+
+void CFX_ListCtrl::Cancel() {
+  m_aSelItems.DeselectAll();
+}
+
+int32_t CFX_ListCtrl::GetItemIndex(const CPDF_Point& point) const {
+  return CFX_List::GetItemIndex(OutToIn(point));
+}
+
+CFX_WideString CFX_ListCtrl::GetText() const {
+  if (IsMultipleSel())
+    return GetItemText(m_nCaretIndex);
+  return GetItemText(m_nSelItem);
+}