Fix bug with removing items from menus with radio buttons in wxMSW.

Update the indices of the radio groups after removing an item from the menu.

See #14213.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@76650 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-06-02 01:13:43 +00:00
parent 5a85e9e98a
commit 6f79fa7a66
2 changed files with 61 additions and 0 deletions

View File

@@ -658,6 +658,7 @@ wxMSW:
- Fix resource leak in wxStaticBitmap with RGBA icons (Artur Wieczorek).
- Fix toolbar repainting after deleting a tool from it (Artur Wieczorek).
- Allow resetting bitmaps used in wxButton (Artur Wieczorek).
- Fix bug with removing items from a menu with radio buttons (Artur Wieczorek).
- Fix handling of deleting directories in wxFileSystemWatcher (Eric Raijmakers).
- Disable the use of new style wxDirDialog under Vista to work around a bug in
its implementation under this system (jtrauntvein).

View File

@@ -169,6 +169,57 @@ public:
return true;
}
// Update the ranges of the existing radio groups after removing the menu
// item at the given position.
//
// The item being removed can be the item of any kind, not only the radio
// button belonging to the radio group, and this function checks for it
// and, as a side effect, returns true if this item was found inside an
// existing radio group.
bool UpdateOnRemoveItem(int pos)
{
bool inExistingGroup = false;
// Pointer to (necessarily unique) empty group which could be left
// after removing the last radio button from it.
Ranges::iterator itEmptyGroup = m_ranges.end();
for ( Ranges::iterator it = m_ranges.begin();
it != m_ranges.end();
++it )
{
Range& r = *it;
if ( pos < r.start )
{
// Removed item was positioned before this range, update its
// indices.
r.start--;
r.end--;
}
else if ( pos <= r.end )
{
// Removed item belongs to this radio group (it is a radio
// button), update index of its end.
r.end--;
// Check if empty group left after removal.
// If so, it will be deleted later on.
if ( r.end < r.start )
itEmptyGroup = it;
inExistingGroup = true;
}
//else: Removed item was after this range, nothing to do for it.
}
// Remove empty group from the list.
if ( itEmptyGroup != m_ranges.end() )
m_ranges.erase(itEmptyGroup);
return inExistingGroup;
}
private:
// Contains the inclusive positions of the range start and end.
struct Range
@@ -827,6 +878,15 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
//else: this item doesn't have an accel, nothing to do
#endif // wxUSE_ACCEL
// Update indices of radio groups.
if ( m_radioData )
{
bool inExistingGroup = m_radioData->UpdateOnRemoveItem(pos);
wxASSERT_MSG( !inExistingGroup || item->GetKind() == wxITEM_RADIO,
wxT("Removing non radio button from radio group?") );
}
// remove the item from the menu
if ( !::RemoveMenu(GetHmenu(), (UINT)pos, MF_BYPOSITION) )
{