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().
(backport of 60542745f6
from master)
This commit is contained in:
@@ -94,6 +94,9 @@ public:
|
|||||||
|
|
||||||
// called by wxMenuItem when its accels changes
|
// called by wxMenuItem when its accels changes
|
||||||
void UpdateAccel(wxMenuItem *item);
|
void UpdateAccel(wxMenuItem *item);
|
||||||
|
#if wxABI_VERSION >= 30002
|
||||||
|
void RemoveAccel(wxMenuItem *item);
|
||||||
|
#endif
|
||||||
|
|
||||||
// helper used by wxMenu itself (returns the index in m_accels)
|
// helper used by wxMenu itself (returns the index in m_accels)
|
||||||
int FindAccel(int id) const;
|
int FindAccel(int id) const;
|
||||||
|
@@ -458,6 +458,33 @@ void wxMenu::UpdateAccel(wxMenuItem *item)
|
|||||||
//else: it is a separator, they can't have accels, nothing to do
|
//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
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -863,19 +890,7 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
|
|||||||
wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
|
wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
// remove the corresponding accel from the accel table
|
RemoveAccel(item);
|
||||||
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
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
// Update indices of radio groups.
|
// Update indices of radio groups.
|
||||||
|
Reference in New Issue
Block a user