1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-16 16:20:50 +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 ){ if( hasWaveform ){
BEGIN_POPUP_MENU_SECTION( "WaveColor" ) BEGIN_POPUP_MENU_SECTION( "WaveColor" )
POPUP_MENU_SUB_MENU( "WaveColor", WaveColorMenuTable) POPUP_MENU_SUB_MENU( "WaveColor", WaveColorMenuTable, mpData )
END_POPUP_MENU_SECTION() END_POPUP_MENU_SECTION()
} }
@ -825,11 +825,11 @@ BEGIN_POPUP_MENU(WaveTrackMenuTable)
END_POPUP_MENU_SECTION() END_POPUP_MENU_SECTION()
BEGIN_POPUP_MENU_SECTION( "Format" ) BEGIN_POPUP_MENU_SECTION( "Format" )
POPUP_MENU_SUB_MENU( "Format", FormatMenuTable) POPUP_MENU_SUB_MENU( "Format", FormatMenuTable, mpData )
END_POPUP_MENU_SECTION() END_POPUP_MENU_SECTION()
BEGIN_POPUP_MENU_SECTION( "Rate" ) 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_SECTION()
END_POPUP_MENU() END_POPUP_MENU()

View File

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

View File

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