Merge branch 'select-after-delete'

Harmonize behaviour of wxItemContainer::Delete() for all controls and
ports when using single selection.

See https://github.com/wxWidgets/wxWidgets/pull/1080

Closes #18267.
This commit is contained in:
Vadim Zeitlin
2019-01-04 14:01:02 +01:00
17 changed files with 92 additions and 48 deletions

View File

@@ -125,6 +125,10 @@ All (GUI):
in wxPGArrayEditorDialog. in wxPGArrayEditorDialog.
- Fix wxPropertyGrid issues with horizontal scrolling. - Fix wxPropertyGrid issues with horizontal scrolling.
wxGTK:
- Invalidate selection after deleting wxListBox item with GTK+ 3 too.
3.1.2: (released 2018-12-10) 3.1.2: (released 2018-12-10)
---------------------------- ----------------------------

View File

@@ -354,6 +354,12 @@ public:
failure in debug builds) to remove an item with the index negative or failure in debug builds) to remove an item with the index negative or
greater or equal than the number of items in the control. greater or equal than the number of items in the control.
If there is a currently selected item below the item being deleted,
i.e. if GetSelection() returns a valid index greater than or equal to
@a n, the selection is invalidated when this function is called.
However if the selected item appears before the item being deleted, the
selection is preserved unchanged.
@param n @param n
The zero-based item index. The zero-based item index.

View File

@@ -62,8 +62,8 @@
@event{EVT_LISTBOX_DCLICK(id, func)} @event{EVT_LISTBOX_DCLICK(id, func)}
Process a @c wxEVT_LISTBOX_DCLICK event, when the listbox Process a @c wxEVT_LISTBOX_DCLICK event, when the listbox
is double-clicked. On some platforms (notably wxGTK2) is double-clicked. On some platforms (notably wxGTK2)
pressing the enter key is handled as an equivalent of a pressing the enter key is handled as an equivalent of a
double-click. double-click.
@endEventTable @endEventTable
@library{wxcore} @library{wxcore}

View File

@@ -801,7 +801,7 @@ public:
The messages will be written in the encoding specified by the The messages will be written in the encoding specified by the
given @c wxMBConv. given @c wxMBConv.
The @a conv argument is only available in wxWidgets 3.1.1 and later. The @a conv argument is only available in wxWidgets 3.1.1 and later.
@note @note
In practice, it is only advisable to specify @c wxConvUTF8 as In practice, it is only advisable to specify @c wxConvUTF8 as

View File

@@ -672,6 +672,18 @@ void wxSimpleHtmlListBox::Clear()
void wxSimpleHtmlListBox::DoDeleteOneItem(unsigned int n) void wxSimpleHtmlListBox::DoDeleteOneItem(unsigned int n)
{ {
// For consistency with the other wxItemContainer-derived classes, deselect
// the currently selected item if it, or any item before it, is being
// deleted, from a single-selection control.
if ( !HasMultipleSelection() )
{
const int sel = GetSelection();
if ( sel != wxNOT_FOUND && static_cast<unsigned>(sel) >= n )
{
SetSelection(wxNOT_FOUND);
}
}
m_items.RemoveAt(n); m_items.RemoveAt(n);
m_HTMLclientData.RemoveAt(n); m_HTMLclientData.RemoveAt(n);

View File

@@ -497,6 +497,25 @@ void wxListBox::DoDeleteOneItem(unsigned int n)
// this returns false if iter is invalid (e.g. deleting item at end) but // this returns false if iter is invalid (e.g. deleting item at end) but
// since we don't use iter, we ignore the return value // since we don't use iter, we ignore the return value
gtk_list_store_remove(m_liststore, &iter); gtk_list_store_remove(m_liststore, &iter);
#ifdef __WXGTK3__
// Invalidate selection in a single-selection control for consistency with
// MSW and GTK+ 2 where this happens automatically when deleting the
// selected item or any item before it.
if ( !HasMultipleSelection() )
{
const int sel = GetSelection();
if ( sel != wxNOT_FOUND && static_cast<unsigned>(sel) >= n )
{
// Don't call SetSelection() from here, it's not totally clear if
// it is safe to do, so just do this at GTK+ level.
gtk_tree_selection_unselect_all
(
gtk_tree_view_get_selection(m_treeview)
);
}
}
#endif // __WXGTK3__
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -77,12 +77,8 @@ private:
wxDECLARE_NO_COPY_CLASS(BitmapComboBoxTestCase); wxDECLARE_NO_COPY_CLASS(BitmapComboBoxTestCase);
}; };
// register in the unnamed registry so that these tests are run by default wxREGISTER_UNIT_TEST_WITH_TAGS(BitmapComboBoxTestCase,
CPPUNIT_TEST_SUITE_REGISTRATION( BitmapComboBoxTestCase ); "[BitmapComboBoxTestCase][item-container]");
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( BitmapComboBoxTestCase,
"BitmapComboBoxTestCase" );
void BitmapComboBoxTestCase::setUp() void BitmapComboBoxTestCase::setUp()
{ {

View File

@@ -46,11 +46,8 @@ private:
wxDECLARE_NO_COPY_CLASS(CheckListBoxTestCase); wxDECLARE_NO_COPY_CLASS(CheckListBoxTestCase);
}; };
// register in the unnamed registry so that these tests are run by default wxREGISTER_UNIT_TEST_WITH_TAGS(CheckListBoxTestCase,
CPPUNIT_TEST_SUITE_REGISTRATION( CheckListBoxTestCase ); "[CheckListBoxTestCase][item-container]");
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CheckListBoxTestCase, "CheckListBoxTestCase" );
void CheckListBoxTestCase::setUp() void CheckListBoxTestCase::setUp()
{ {

View File

@@ -45,11 +45,8 @@ private:
wxDECLARE_NO_COPY_CLASS(ChoiceTestCase); wxDECLARE_NO_COPY_CLASS(ChoiceTestCase);
}; };
// register in the unnamed registry so that these tests are run by default wxREGISTER_UNIT_TEST_WITH_TAGS(ChoiceTestCase,
CPPUNIT_TEST_SUITE_REGISTRATION( ChoiceTestCase ); "[ChoiceTestCase][item-container]");
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ChoiceTestCase, "ChoiceTestCase" );
void ChoiceTestCase::setUp() void ChoiceTestCase::setUp()
{ {

View File

@@ -88,11 +88,8 @@ private:
wxDECLARE_NO_COPY_CLASS(ComboBoxTestCase); wxDECLARE_NO_COPY_CLASS(ComboBoxTestCase);
}; };
// register in the unnamed registry so that these tests are run by default wxREGISTER_UNIT_TEST_WITH_TAGS(ComboBoxTestCase,
CPPUNIT_TEST_SUITE_REGISTRATION( ComboBoxTestCase ); "[ComboBoxTestCase][item-container]");
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ComboBoxTestCase, "ComboBoxTestCase" );
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// test initialization // test initialization

View File

@@ -43,11 +43,8 @@ private:
wxDECLARE_NO_COPY_CLASS(HtmlListBoxTestCase); wxDECLARE_NO_COPY_CLASS(HtmlListBoxTestCase);
}; };
// register in the unnamed registry so that these tests are run by default wxREGISTER_UNIT_TEST_WITH_TAGS(HtmlListBoxTestCase,
CPPUNIT_TEST_SUITE_REGISTRATION( HtmlListBoxTestCase ); "[HtmlListBoxTestCase][item-container]");
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( HtmlListBoxTestCase, "HtmlListBoxTestCase" );
void HtmlListBoxTestCase::setUp() void HtmlListBoxTestCase::setUp()
{ {

View File

@@ -270,6 +270,33 @@ void ItemContainerTestCase::SetString()
#endif #endif
} }
void ItemContainerTestCase::SelectionAfterDelete()
{
wxItemContainer * const container = GetContainer();
container->Append("item 0");
container->Append("item 1");
container->Append("item 2");
container->Append("item 3");
container->SetSelection(1);
CHECK( container->GetSelection() == 1 );
container->Delete(3);
CHECK( container->GetSelection() == 1 );
container->Delete(1);
CHECK( container->GetSelection() == wxNOT_FOUND );
container->SetSelection(1);
container->Delete(1);
CHECK( container->GetSelection() == wxNOT_FOUND );
container->SetSelection(0);
container->Delete(0);
CHECK( container->GetSelection() == wxNOT_FOUND );
}
void ItemContainerTestCase::SetSelection() void ItemContainerTestCase::SetSelection()
{ {
wxItemContainer * const container = GetContainer(); wxItemContainer * const container = GetContainer();

View File

@@ -24,7 +24,7 @@ protected:
// and this one must be overridden to return the window which implements // and this one must be overridden to return the window which implements
// wxItemContainer interface -- usually it will return the same pointer as // wxItemContainer interface -- usually it will return the same pointer as
// GetTestEntry(), just as a different type // GetContainer(), just as a different type
virtual wxWindow *GetContainerWindow() const = 0; virtual wxWindow *GetContainerWindow() const = 0;
// this should be inserted in the derived class CPPUNIT_TEST_SUITE // this should be inserted in the derived class CPPUNIT_TEST_SUITE
@@ -40,6 +40,7 @@ protected:
CPPUNIT_TEST( Set ); \ CPPUNIT_TEST( Set ); \
CPPUNIT_TEST( SetSelection ); \ CPPUNIT_TEST( SetSelection ); \
CPPUNIT_TEST( SetString ); \ CPPUNIT_TEST( SetString ); \
CPPUNIT_TEST( SelectionAfterDelete ); \
WXUISIM_TEST( SimSelect ); WXUISIM_TEST( SimSelect );
void Append(); void Append();
@@ -52,6 +53,7 @@ protected:
void Set(); void Set();
void SetSelection(); void SetSelection();
void SetString(); void SetString();
void SelectionAfterDelete();
#if wxUSE_UIACTIONSIMULATOR #if wxUSE_UIACTIONSIMULATOR
virtual void SimSelect(); virtual void SimSelect();
#endif #endif

View File

@@ -68,11 +68,8 @@ private:
wxDECLARE_NO_COPY_CLASS(ListBoxTestCase); wxDECLARE_NO_COPY_CLASS(ListBoxTestCase);
}; };
// register in the unnamed registry so that these tests are run by default wxREGISTER_UNIT_TEST_WITH_TAGS(ListBoxTestCase,
CPPUNIT_TEST_SUITE_REGISTRATION( ListBoxTestCase ); "[ListBoxTestCase][item-container]");
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ListBoxTestCase, "ListBoxTestCase" );
//initialise the static variable //initialise the static variable
bool ListBoxTestCase::ms_ownerdrawn = false; bool ListBoxTestCase::ms_ownerdrawn = false;

View File

@@ -75,12 +75,8 @@ private:
wxDECLARE_NO_COPY_CLASS(OwnerDrawnComboBoxTestCase); wxDECLARE_NO_COPY_CLASS(OwnerDrawnComboBoxTestCase);
}; };
// register in the unnamed registry so that these tests are run by default wxREGISTER_UNIT_TEST_WITH_TAGS(OwnerDrawnComboBoxTestCase,
CPPUNIT_TEST_SUITE_REGISTRATION( OwnerDrawnComboBoxTestCase ); "[OwnerDrawnComboBoxTestCase][item-container]");
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( OwnerDrawnComboBoxTestCase,
"OwnerDrawnComboBoxTestCase" );
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// test initialization // test initialization

View File

@@ -46,11 +46,8 @@ private:
wxDECLARE_NO_COPY_CLASS(RearrangeListTestCase); wxDECLARE_NO_COPY_CLASS(RearrangeListTestCase);
}; };
// register in the unnamed registry so that these tests are run by default wxREGISTER_UNIT_TEST_WITH_TAGS(RearrangeListTestCase,
CPPUNIT_TEST_SUITE_REGISTRATION( RearrangeListTestCase ); "[RearrangeListTestCase][item-container]");
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( RearrangeListTestCase, "RearrangeListTestCase" );
void RearrangeListTestCase::setUp() void RearrangeListTestCase::setUp()
{ {