Fix accel handling when removing item from submenu

wxMSW propagates accelerators to the top menu in wxMenu::UpdateAccel(),
but the reverse operation in wxMenu::DoRemove() didn't do it, resulting
in leaked leftover accelerator entries that could prevent the same
accelerator from working if an item using it was later added. Fix by
adding RemoveAccel() helper method that behaves analogously to
UpdateAccel().
This commit is contained in:
Václav Slavík
2016-12-05 17:59:03 +01:00
parent 4f0c6c9a3a
commit 60542745f6
2 changed files with 29 additions and 13 deletions

View File

@@ -76,6 +76,7 @@ public:
// called by wxMenuItem when its accels changes
void UpdateAccel(wxMenuItem *item);
void RemoveAccel(wxMenuItem *item);
// helper used by wxMenu itself (returns the index in m_accels)
int FindAccel(int id) const;

View File

@@ -417,6 +417,33 @@ void wxMenu::UpdateAccel(wxMenuItem *item)
//else: it is a separator, they can't have accels, nothing to do
}
void wxMenu::RemoveAccel(wxMenuItem *item)
{
// recurse upwards: we should only modify m_accels of the top level
// menus, not of the submenus as wxMenuBar doesn't look at them
// (alternative and arguable cleaner solution would be to recurse
// downwards in GetAccelCount() and CopyAccels())
if ( GetParent() )
{
GetParent()->RemoveAccel(item);
return;
}
// remove the corresponding accel from the accel table
int n = FindAccel(item->GetId());
if ( n != wxNOT_FOUND )
{
delete m_accels[n];
m_accels.RemoveAt(n);
#if wxUSE_OWNER_DRAWN
ResetMaxAccelWidth();
#endif
}
//else: this item doesn't have an accel, nothing to do
}
#endif // wxUSE_ACCEL
namespace
@@ -735,19 +762,7 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
}
#if wxUSE_ACCEL
// remove the corresponding accel from the accel table
int n = FindAccel(item->GetId());
if ( n != wxNOT_FOUND )
{
delete m_accels[n];
m_accels.RemoveAt(n);
#if wxUSE_OWNER_DRAWN
ResetMaxAccelWidth();
#endif
}
//else: this item doesn't have an accel, nothing to do
RemoveAccel(item);
#endif // wxUSE_ACCEL
// Update indices of radio groups.