From 8bf53a7782c2c1b065fd7779a74e82621daecfe5 Mon Sep 17 00:00:00 2001 From: Andreas Falkenhahn Date: Sat, 5 Dec 2020 22:45:13 +0100 Subject: [PATCH] Fix selection after inserting items in wxListBox in wxOSX We need to adjust the indices of the currently selected items as we need to keep the same items, not the same indices, selected after new items insertion. Closes #18902. --- include/wx/osx/listbox.h | 2 ++ src/osx/listbox_osx.cpp | 52 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/include/wx/osx/listbox.h b/include/wx/osx/listbox.h index 5e8949e700..ed86f5c7d8 100644 --- a/include/wx/osx/listbox.h +++ b/include/wx/osx/listbox.h @@ -170,6 +170,8 @@ protected: wxArrayPtrVoid m_itemsClientData; private: + // Mostly the same as DoSetSelection() but doesn't call EnsureVisible(). + void DoSetSelectionWithoutEnsureVisible(int n, bool select); wxDECLARE_DYNAMIC_CLASS(wxListBox); wxDECLARE_EVENT_TABLE(); diff --git a/src/osx/listbox_osx.cpp b/src/osx/listbox_osx.cpp index e153fb48a1..961141df13 100644 --- a/src/osx/listbox_osx.cpp +++ b/src/osx/listbox_osx.cpp @@ -191,6 +191,14 @@ void wxListBox::DoSetSelection(int n, bool select) wxCHECK_RET( n == wxNOT_FOUND || IsValid(n), wxT("invalid index in wxListBox::SetSelection") ); + DoSetSelectionWithoutEnsureVisible(n, select); + + if (select) + EnsureVisible(n); +} + +void wxListBox::DoSetSelectionWithoutEnsureVisible(int n, bool select) +{ m_blockEvents = true; if ( n == wxNOT_FOUND ) @@ -201,9 +209,6 @@ void wxListBox::DoSetSelection(int n, bool select) m_blockEvents = false; UpdateOldSelections(); - - if (select) - EnsureVisible(n); } bool wxListBox::IsSelected(int n) const @@ -349,6 +354,23 @@ int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, { int idx = wxNOT_FOUND; unsigned int startpos = pos; + wxArrayInt selections; + + if ( !IsSorted() ) + { + if ( HasMultipleSelection() ) + { + GetSelections(selections); + } + else + { + int sel = GetSelection(); + if ( sel != wxNOT_FOUND ) + { + selections.Add(sel); + } + } + } const unsigned int numItems = items.GetCount(); for ( unsigned int i = 0; i < numItems; ++i ) @@ -367,6 +389,30 @@ int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, GetListPeer()->UpdateLineToEnd(startpos); + const size_t numSelections = selections.size(); + for ( size_t i = 0; i < numSelections; ++i ) + { + if ( startpos <= selections[i] ) + { + if ( HasMultipleSelection() ) + { + size_t j; + + // Do not deselect item if it is to be selected below + for ( j = 0; j < numSelections; ++j ) + { + if ( selections[i] == selections[j] + numItems ) + break; + } + + if ( j == numSelections ) + Deselect(selections[i]); + } + + DoSetSelectionWithoutEnsureVisible(selections[i] + numItems, true); + } + } + InvalidateBestSize(); UpdateOldSelections();