1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-17 00:20:06 +02:00

Bug2312: don't crash using Wave Color, Format, Rate sub-menus of TCP

This commit is contained in:
Paul Licameli 2020-02-08 13:01:23 -05:00
parent c2888302fd
commit 8f88aa106e
3 changed files with 16 additions and 15 deletions

View File

@ -792,7 +792,7 @@ BEGIN_POPUP_MENU(WaveTrackMenuTable)
) );
if( hasWaveform ){
BEGIN_POPUP_MENU_SECTION( "WaveColor" )
POPUP_MENU_SUB_MENU( "WaveColor", WaveColorMenuTable)
POPUP_MENU_SUB_MENU( "WaveColor", WaveColorMenuTable, mpData )
END_POPUP_MENU_SECTION()
}
@ -825,11 +825,11 @@ BEGIN_POPUP_MENU(WaveTrackMenuTable)
END_POPUP_MENU_SECTION()
BEGIN_POPUP_MENU_SECTION( "Format" )
POPUP_MENU_SUB_MENU( "Format", FormatMenuTable)
POPUP_MENU_SUB_MENU( "Format", FormatMenuTable, mpData )
END_POPUP_MENU_SECTION()
BEGIN_POPUP_MENU_SECTION( "Rate" )
POPUP_MENU_SUB_MENU( "Rate", RateMenuTable)
POPUP_MENU_SUB_MENU( "Rate", RateMenuTable, mpData )
END_POPUP_MENU_SECTION()
END_POPUP_MENU()

View File

@ -18,10 +18,11 @@ PopupSubMenu::~PopupSubMenu()
{}
PopupSubMenu::PopupSubMenu( const Identifier &stringId,
const TranslatableString &caption_, PopupMenuTable &table )
const TranslatableString &caption_, PopupMenuTable &table_ )
: ConcreteGroupItem< false >{ stringId }
, WholeMenu{ caption_.empty() }
, caption{ caption_ }
, table{ table_ }
{
}
@ -69,6 +70,7 @@ void PopupMenuBuilder::DoBeginGroup( Registry::GroupItem &item, const Path &path
if ( !pItem->caption.empty() ) {
auto newMenu =
std::make_unique<PopupMenu>( mMenu->pParent, mMenu->pUserData );
newMenu->tables.push_back( &pItem->table );
mMenu = newMenu.get();
mMenus.push_back( std::move( newMenu ) );
}
@ -78,6 +80,7 @@ void PopupMenuBuilder::DoBeginGroup( Registry::GroupItem &item, const Path &path
void PopupMenuBuilder::DoEndGroup( Registry::GroupItem &item, const Path &path )
{
if ( auto pItem = dynamic_cast<PopupSubMenu*>(&item) ) {
pItem->table.InitMenu( mMenu );
if ( !pItem->caption.empty() ) {
auto subMenu = std::move( mMenus.back() );
mMenus.pop_back();
@ -92,7 +95,7 @@ void PopupMenuBuilder::DoVisit( Registry::SingleItem &item, const Path &path )
auto connect = [this]( const PopupMenuTable::Entry *pEntry ) {
mMenu->pParent->Bind
(wxEVT_COMMAND_MENU_SELECTED,
pEntry->func, &mTable, pEntry->id);
pEntry->func, mMenu->tables.back(), pEntry->id);
};
auto pEntry = static_cast<PopupMenuTableEntry*>( &item );
@ -136,14 +139,10 @@ PopupMenu::~PopupMenu()
void PopupMenuTable::ExtendMenu( wxMenu &menu, PopupMenuTable &table )
{
auto &theMenu = dynamic_cast<PopupMenu&>(menu);
table.InitUserData(theMenu.pUserData);
theMenu.tables.push_back( &table );
PopupMenuBuilder visitor{ table, theMenu, theMenu.pUserData };
Registry::Visit( visitor, table.Get().get() );
table.InitMenu( &menu );
theMenu.tables.push_back( &table );
Registry::Visit( visitor, table.Get( theMenu.pUserData ).get() );
}
namespace{
@ -169,7 +168,7 @@ void PopupMenu::DisconnectTable(PopupMenuTable *pTable)
};
PopupMenuDestroyer visitor{ *pTable, *this };
Registry::Visit( visitor, pTable->Get().get() );
Registry::Visit( visitor, pTable->Get( nullptr ).get() );
pTable->DestroyMenu();
}

View File

@ -56,6 +56,7 @@ struct PopupSubMenu : Registry::ConcreteGroupItem< false >
, MenuTable::WholeMenu
{
TranslatableString caption;
PopupMenuTable &table;
PopupSubMenu( const Identifier &stringId,
const TranslatableString &caption_, PopupMenuTable &table );
@ -104,8 +105,9 @@ public:
// More items get added to the end of it
static void ExtendMenu( wxMenu &menu, PopupMenuTable &otherTable );
const std::shared_ptr< Registry::GroupItem > &Get()
const std::shared_ptr< Registry::GroupItem > &Get( void *pUserData )
{
this->InitUserData( pUserData );
if (!mTop)
Populate();
return mTop;
@ -216,9 +218,9 @@ void HandlerClass::Populate() { \
POPUP_MENU_APPEND_ITEM(stringId, Entry::CheckItem, id, string, memFn);
// classname names a class that derives from MenuTable and defines Instance()
#define POPUP_MENU_SUB_MENU(stringId, classname) \
#define POPUP_MENU_SUB_MENU(stringId, classname, pUserData ) \
mStack.back()->items.push_back( \
Registry::Shared( classname::Instance().Get() ) );
Registry::Shared( classname::Instance().Get( pUserData ) ) );
#define BEGIN_POPUP_MENU_SECTION( name ) \
{ auto uSection = std::make_unique< PopupMenuSection >( \