diff --git a/lib-src/mod-null/ModNullCallback.cpp b/lib-src/mod-null/ModNullCallback.cpp index 454d38847..48bf8f3d2 100644 --- a/lib-src/mod-null/ModNullCallback.cpp +++ b/lib-src/mod-null/ModNullCallback.cpp @@ -113,7 +113,7 @@ void ModNullCallback::OnFuncSecond(const CommandContext &) } ModNullCallback * pModNullCallback=NULL; -#define ModNullFN(X) ident, static_cast(&ModNullCallback:: X) +#define ModNullFN(X) static_cast((&ModNullCallback:: X)) extern "C" { @@ -163,12 +163,12 @@ int ModuleDispatch(ModuleDispatchTypes type) c->AddItem( _T("A New Command"), // internal name XO("1st Experimental Command..."), //displayed name - ModNullFN( OnFuncFirst ), + ident, ModNullFN( OnFuncFirst ), AudioIONotBusyFlag ); c->AddItem( - _T("Another New Command"), + _T("Another New Command"), XO("2nd Experimental Command"), - ModNullFN( OnFuncSecond ), + ident, ModNullFN( OnFuncSecond ), AudioIONotBusyFlag ); c->ClearCurrentMenu(); } diff --git a/src/Menus.cpp b/src/Menus.cpp index 0e352a291..4f285ee90 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -134,10 +134,10 @@ SeparatorItem::~SeparatorItem() {} CommandItem::CommandItem(const CommandID &name_, const TranslatableString &label_in_, - CommandHandlerFinder finder_, CommandFunctorPointer callback_, CommandFlag flags_, - const CommandManager::Options &options_) + const CommandManager::Options &options_, + CommandHandlerFinder finder_) : name{ name_ }, label_in{ label_in_ } , finder{ finder_ }, callback{ callback_ } , flags{ flags_ }, options{ options_ } @@ -146,10 +146,10 @@ CommandItem::~CommandItem() {} CommandGroupItem::CommandGroupItem(const wxString &name_, std::initializer_list< ComponentInterfaceSymbol > items_, - CommandHandlerFinder finder_, CommandFunctorPointer callback_, CommandFlag flags_, - bool isEffect_) + bool isEffect_, + CommandHandlerFinder finder_) : name{ name_ }, items{ items_ } , finder{ finder_ }, callback{ callback_ } , flags{ flags_ }, isEffect{ isEffect_ } @@ -158,6 +158,15 @@ CommandGroupItem::~CommandGroupItem() {} SpecialItem::~SpecialItem() {} +CommandHandlerFinder FinderScope::sFinder = + [](AudacityProject &project) -> CommandHandlerObject & { + // If this default finder function is reached, then FinderScope should + // have been used somewhere, or an explicit CommandHandlerFinder passed + // to menu item constructors + wxASSERT( false ); + return project; + }; + } namespace { diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index 7e5e10bfc..82d1bba8e 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -490,13 +490,57 @@ namespace MenuTable { ~SeparatorItem() override; }; + // usage: + // auto scope = FinderScope( findCommandHandler ); + // return Items( ... ); + // + // or: + // return FinderScope( findCommandHandler ) + // .Eval( Items( ... ) ); + // + // where findCommandHandler names a function. + // This is used before a sequence of many calls to Command() and + // CommandGroup(), so that the finder argument need not be specified + // in each call. + class FinderScope : ValueRestorer< CommandHandlerFinder > + { + static CommandHandlerFinder sFinder; + + public: + static CommandHandlerFinder DefaultFinder() { return sFinder; } + + explicit + FinderScope( CommandHandlerFinder finder ) + : ValueRestorer( sFinder, finder ) + {} + + // See usage comment above about this pass-through function + template< typename Value > Value&& Eval( Value &&value ) const + { return std::forward(value); } + }; + struct CommandItem final : BaseItem { CommandItem(const CommandID &name_, const TranslatableString &label_in_, - CommandHandlerFinder finder_, CommandFunctorPointer callback_, CommandFlag flags_, - const CommandManager::Options &options_); + const CommandManager::Options &options_, + CommandHandlerFinder finder_); + + // Takes a pointer to member function directly, and delegates to the + // previous constructor; useful within the lifetime of a FinderScope + template< typename Handler > + CommandItem(const CommandID &name_, + const TranslatableString &label_in_, + void (Handler::*pmf)(const CommandContext&), + CommandFlag flags_, + const CommandManager::Options &options_, + CommandHandlerFinder finder = FinderScope::DefaultFinder()) + : CommandItem(name_, label_in_, + static_cast(pmf), + flags_, options_, finder) + {} + ~CommandItem() override; const CommandID name; @@ -510,10 +554,25 @@ namespace MenuTable { struct CommandGroupItem final : BaseItem { CommandGroupItem(const wxString &name_, std::initializer_list< ComponentInterfaceSymbol > items_, - CommandHandlerFinder finder_, CommandFunctorPointer callback_, CommandFlag flags_, - bool isEffect_); + bool isEffect_, + CommandHandlerFinder finder_); + + // Takes a pointer to member function directly, and delegates to the + // previous constructor; useful within the lifetime of a FinderScope + template< typename Handler > + CommandGroupItem(const wxString &name_, + std::initializer_list< ComponentInterfaceSymbol > items_, + void (Handler::*pmf)(const CommandContext&), + CommandFlag flags_, + bool isEffect_, + CommandHandlerFinder finder = FinderScope::DefaultFinder()) + : CommandGroupItem(name_, items_, + static_cast(pmf), + flags_, isEffect_, finder) + {} + ~CommandGroupItem() override; const wxString name; @@ -588,25 +647,29 @@ namespace MenuTable { inline std::unique_ptr Separator() { return std::make_unique(); } + template< typename Handler > inline std::unique_ptr Command( const CommandID &name, const TranslatableString &label_in, - CommandHandlerFinder finder, CommandFunctorPointer callback, - CommandFlag flags, const CommandManager::Options &options = {}) + void (Handler::*pmf)(const CommandContext&), + CommandFlag flags, const CommandManager::Options &options = {}, + CommandHandlerFinder finder = FinderScope::DefaultFinder()) { return std::make_unique( - name, label_in, finder, callback, flags, options + name, label_in, pmf, flags, options, finder ); } + template< typename Handler > inline std::unique_ptr CommandGroup( const wxString &name, std::initializer_list< ComponentInterfaceSymbol > items, - CommandHandlerFinder finder, CommandFunctorPointer callback, - CommandFlag flags, bool isEffect = false) + void (Handler::*pmf)(const CommandContext&), + CommandFlag flags, bool isEffect = false, + CommandHandlerFinder finder = FinderScope::DefaultFinder()) { return std::make_unique( - name, items, finder, callback, flags, isEffect + name, items, pmf, flags, isEffect, finder ); } diff --git a/src/menus/ClipMenus.cpp b/src/menus/ClipMenus.cpp index 67cab6d24..ae7deba59 100644 --- a/src/menus/ClipMenus.cpp +++ b/src/menus/ClipMenus.cpp @@ -821,15 +821,15 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& ClipActions::Handler :: X) +#define FN(X) (& ClipActions::Handler :: X) MenuTable::BaseItemPtr ClipSelectMenu( AudacityProject& ) { using namespace MenuTable; using Options = CommandManager::Options; - return Menu( XO("Clip B&oundaries"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("Clip B&oundaries"), Command( wxT("SelPrevClipBoundaryToCursor"), XXO("Pre&vious Clip Boundary to Cursor"), FN(OnSelectPrevClipBoundaryToCursor), @@ -844,7 +844,7 @@ MenuTable::BaseItemPtr ClipSelectMenu( AudacityProject& ) Command( wxT("SelNextClip"), XXO("N&ext Clip"), FN(OnSelectNextClip), WaveTracksExistFlag, Options{ wxT("Alt+."), XO("Select Next Clip") } ) - ); + ) ); } MenuTable::BaseItemPtr ClipCursorItems( AudacityProject & ) @@ -852,7 +852,8 @@ MenuTable::BaseItemPtr ClipCursorItems( AudacityProject & ) using namespace MenuTable; using Options = CommandManager::Options; - return Items( + return FinderScope( findCommandHandler ).Eval( + Items( Command( wxT("CursPrevClipBoundary"), XXO("Pre&vious Clip Boundary"), FN(OnCursorPrevClipBoundary), WaveTracksExistFlag, @@ -861,19 +862,20 @@ MenuTable::BaseItemPtr ClipCursorItems( AudacityProject & ) FN(OnCursorNextClipBoundary), WaveTracksExistFlag, Options{}.LongName( XO("Cursor to Next Clip Boundary") ) ) - ); + ) ); } MenuTable::BaseItemPtr ExtraClipCursorItems( AudacityProject & ) { using namespace MenuTable; - return Items( + return FinderScope( findCommandHandler ).Eval( + Items( Command( wxT("ClipLeft"), XXO("Clip L&eft"), FN(OnClipLeft), TracksExistFlag | TrackPanelHasFocus, wxT("\twantKeyup") ), Command( wxT("ClipRight"), XXO("Clip Rig&ht"), FN(OnClipRight), TracksExistFlag | TrackPanelHasFocus, wxT("\twantKeyup") ) - ); + ) ); } #undef FN diff --git a/src/menus/EditMenus.cpp b/src/menus/EditMenus.cpp index 20dad1d76..abe3690c2 100644 --- a/src/menus/EditMenus.cpp +++ b/src/menus/EditMenus.cpp @@ -995,8 +995,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& EditActions::Handler :: X) +#define FN(X) (& EditActions::Handler :: X) MenuTable::BaseItemPtr LabelEditMenus( AudacityProject &project ); @@ -1052,7 +1051,8 @@ MenuTable::BaseItemPtr EditMenu( AudacityProject & ) #endif ; - return Menu( XO("&Edit"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Edit"), Command( wxT("Undo"), XXO("&Undo"), FN(OnUndo), AudioIONotBusyFlag | UndoAvailableFlag, wxT("Ctrl+Z") ), @@ -1145,7 +1145,7 @@ MenuTable::BaseItemPtr EditMenu( AudacityProject & ) Command( wxT("Preferences"), XXO("Pre&ferences..."), FN(OnPreferences), AudioIONotBusyFlag, prefKey ) - ); + ) ); } MenuTable::BaseItemPtr ExtraEditMenu( AudacityProject & ) @@ -1154,14 +1154,16 @@ MenuTable::BaseItemPtr ExtraEditMenu( AudacityProject & ) using Options = CommandManager::Options; static const auto flags = AudioIONotBusyFlag | TracksSelectedFlag | TimeSelectedFlag; - return Menu( XO("&Edit"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Edit"), Command( wxT("DeleteKey"), XXO("&Delete Key"), FN(OnDelete), (flags | NoAutoSelect), wxT("Backspace") ), Command( wxT("DeleteKey2"), XXO("Delete Key&2"), FN(OnDelete), (flags | NoAutoSelect), wxT("Delete") ) - ); + ) ); } auto canSelectAll = [](const AudacityProject &project){ diff --git a/src/menus/ExtraMenus.cpp b/src/menus/ExtraMenus.cpp index a77dbfbff..18ebc3e75 100644 --- a/src/menus/ExtraMenus.cpp +++ b/src/menus/ExtraMenus.cpp @@ -134,8 +134,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& ExtraActions::Handler :: X) +#define FN(X) (& ExtraActions::Handler :: X) // Imported menu item definitions @@ -193,7 +192,9 @@ MenuTable::BaseItemPtr ExtraMenu( AudacityProject & ) MenuTable::BaseItemPtr ExtraMixerMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("Mi&xer"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("Mi&xer"), Command( wxT("OutputGain"), XXO("Ad&just Playback Volume..."), FN(OnOutputGain), AlwaysEnabledFlag ), Command( wxT("OutputGainInc"), XXO("&Increase Playback Volume"), @@ -206,13 +207,15 @@ MenuTable::BaseItemPtr ExtraMixerMenu( AudacityProject & ) FN(OnInputGainInc), AlwaysEnabledFlag ), Command( wxT("InputGainDec"), XXO("D&ecrease Recording Volume"), FN(OnInputGainDec), AlwaysEnabledFlag ) - ); + ) ); } MenuTable::BaseItemPtr ExtraDeviceMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("De&vice"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("De&vice"), Command( wxT("InputDevice"), XXO("Change &Recording Device..."), FN(OnInputDevice), AudioIONotBusyFlag, wxT("Shift+I") ), @@ -224,7 +227,7 @@ MenuTable::BaseItemPtr ExtraDeviceMenu( AudacityProject & ) Command( wxT("InputChannels"), XXO("Change Recording Cha&nnels..."), FN(OnInputChannels), AudioIONotBusyFlag, wxT("Shift+N") ) - ); + ) ); } MenuTable::BaseItemPtr ExtraMiscItems( AudacityProject &project ) @@ -241,7 +244,9 @@ MenuTable::BaseItemPtr ExtraMiscItems( AudacityProject &project ) ; // Not a menu. - return Items( + + return FinderScope( findCommandHandler ).Eval( + Items( // Accel key is not bindable. Command( wxT("FullScreenOnOff"), XXO("&Full Screen (on/off)"), FN(OnFullScreen), @@ -250,7 +255,7 @@ MenuTable::BaseItemPtr ExtraMiscItems( AudacityProject &project ) GetProjectFrame( project ).wxTopLevelWindow::IsFullScreen() ) ), ExtraWindowItems - ); + ) ); } #undef FN diff --git a/src/menus/FileMenus.cpp b/src/menus/FileMenus.cpp index b7c29e025..13de72199 100644 --- a/src/menus/FileMenus.cpp +++ b/src/menus/FileMenus.cpp @@ -549,15 +549,15 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& FileActions::Handler :: X) +#define FN(X) (& FileActions::Handler :: X) MenuTable::BaseItemPtr FileMenu( AudacityProject& ) { using namespace MenuTable; using Options = CommandManager::Options; - return Menu( XO("&File"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&File"), /*i18n-hint: "New" is an action (verb) to create a NEW project*/ Command( wxT("New"), XXO("&New"), FN(OnNew), AudioIONotBusyFlag, wxT("Ctrl+N") ), @@ -698,7 +698,7 @@ MenuTable::BaseItemPtr FileMenu( AudacityProject& ) /* i18n-hint: (verb) It's item on a menu. */ Command( wxT("Exit"), XXO("E&xit"), FN(OnExit), AlwaysEnabledFlag, wxT("Ctrl+Q") ) - ); + ) ); } #undef FN diff --git a/src/menus/HelpMenus.cpp b/src/menus/HelpMenus.cpp index 2a79f55b2..cd3d5aac3 100644 --- a/src/menus/HelpMenus.cpp +++ b/src/menus/HelpMenus.cpp @@ -418,8 +418,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& HelpActions::Handler :: X) +#define FN(X) (& HelpActions::Handler :: X) MenuTable::BaseItemPtr HelpMenu( AudacityProject & ) { @@ -429,7 +428,8 @@ MenuTable::BaseItemPtr HelpMenu( AudacityProject & ) using namespace MenuTable; - return Menu( XO("&Help"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Help"), // QuickFix menu item not in Audacity 2.3.1 whilst we discuss further. #ifdef EXPERIMENTAL_DA // DA: Has QuickFix menu item. @@ -480,7 +480,7 @@ MenuTable::BaseItemPtr HelpMenu( AudacityProject & ) #endif Command( wxT("About"), XXO("&About Audacity..."), FN(OnAbout), AlwaysEnabledFlag ) - ); + ) ); } #undef FN diff --git a/src/menus/LabelMenus.cpp b/src/menus/LabelMenus.cpp index 696068267..21a72b3b7 100644 --- a/src/menus/LabelMenus.cpp +++ b/src/menus/LabelMenus.cpp @@ -559,8 +559,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& LabelEditActions::Handler :: X) +#define FN(X) (& LabelEditActions::Handler :: X) MenuTable::BaseItemPtr LabelEditMenus( AudacityProject & ) { @@ -575,7 +574,9 @@ MenuTable::BaseItemPtr LabelEditMenus( AudacityProject & ) // Returns TWO menus. - return Items( + + return FinderScope( findCommandHandler ).Eval( + Items( Menu( XO("&Labels"), Command( wxT("EditLabels"), XXO("&Edit Labels..."), FN(OnEditLabels), @@ -653,7 +654,7 @@ MenuTable::BaseItemPtr LabelEditMenus( AudacityProject & ) wxT("Alt+Shift+J") ) ) // second menu - ); // two menus + ) ); // two menus } #undef FN diff --git a/src/menus/NavigationMenus.cpp b/src/menus/NavigationMenus.cpp index 131164b18..60572531e 100644 --- a/src/menus/NavigationMenus.cpp +++ b/src/menus/NavigationMenus.cpp @@ -553,22 +553,23 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &project) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& NavigationActions::Handler :: X) +#define FN(X) (& NavigationActions::Handler :: X) MenuTable::BaseItemPtr ExtraGlobalCommands( AudacityProject & ) { // Ceci n'est pas un menu using namespace MenuTable; using Options = CommandManager::Options; - return Items( + + return FinderScope( findCommandHandler ).Eval( + Items( Command( wxT("PrevWindow"), XXO("Move Backward Through Active Windows"), FN(OnPrevWindow), AlwaysEnabledFlag, Options{ wxT("Alt+Shift+F6") }.IsGlobal() ), Command( wxT("NextWindow"), XXO("Move Forward Through Active Windows"), FN(OnNextWindow), AlwaysEnabledFlag, Options{ wxT("Alt+F6") }.IsGlobal() ) - ); + ) ); } MenuTable::BaseItemPtr ExtraFocusMenu( AudacityProject & ) @@ -576,7 +577,8 @@ MenuTable::BaseItemPtr ExtraFocusMenu( AudacityProject & ) using namespace MenuTable; static const auto FocusedTracksFlags = TracksExistFlag | TrackPanelHasFocus; - return Menu( XO("F&ocus"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("F&ocus"), Command( wxT("PrevFrame"), XXO("Move &Backward from Toolbars to Tracks"), FN(OnPrevFrame), AlwaysEnabledFlag, wxT("Ctrl+Shift+F6") ), @@ -599,7 +601,7 @@ MenuTable::BaseItemPtr ExtraFocusMenu( AudacityProject & ) FocusedTracksFlags, wxT("Return") ), Command( wxT("ToggleAlt"), XXO("Toggle Focuse&d Track"), FN(OnToggle), FocusedTracksFlags, wxT("NUMPAD_ENTER") ) - ); + ) ); } #undef FN diff --git a/src/menus/PluginMenus.cpp b/src/menus/PluginMenus.cpp index 4e25bfd8e..10792e024 100644 --- a/src/menus/PluginMenus.cpp +++ b/src/menus/PluginMenus.cpp @@ -585,8 +585,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions? ... -#define FN(X) findCommandHandler, \ - static_cast(& PluginActions::Handler :: X) +#define FN(X) (& PluginActions::Handler :: X) // ... buf first some more helper definitions, which use FN namespace { @@ -632,6 +631,8 @@ void AddEffectMenuItemGroup( } using namespace MenuTable; + // This finder scope may be redundant, but harmless + auto scope = FinderScope( findCommandHandler ); auto pTable = &table; BaseItemPtrs temp1; @@ -721,6 +722,8 @@ MenuTable::BaseItemPtrs PopulateMacrosMenu( CommandFlag flags ) auto names = MacroCommands::GetNames(); // these names come from filenames int i; + // This finder scope may be redundant, but harmless + auto scope = MenuTable::FinderScope( findCommandHandler ); for (i = 0; i < (int)names.size(); i++) { auto MacroID = ApplyMacroDialog::MacroIdOfName( names[i] ); result.push_back( MenuTable::Command( MacroID, @@ -744,7 +747,8 @@ MenuTable::BaseItemPtr GenerateMenu( AudacityProject & ) // All of this is a bit hacky until we can get more things connected into // the plugin manager...sorry! :-( - return Menu( XO("&Generate"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Generate"), #ifdef EXPERIMENTAL_EFFECT_MANAGEMENT Command( wxT("ManageGenerators"), XXO("Add / Remove Plug-ins..."), FN(OnManageGenerators), AudioIONotBusyFlag ), @@ -757,7 +761,7 @@ MenuTable::BaseItemPtr GenerateMenu( AudacityProject & ) EffectTypeGenerate, AudioIONotBusyFlag, AudioIONotBusyFlag) ) - ); + ) ); } const ReservedCommandFlag @@ -781,7 +785,8 @@ MenuTable::BaseItemPtr EffectMenu( AudacityProject &project ) else buildMenuLabel = XO("Repeat Last Effect"); - return Menu( XO("Effe&ct"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("Effe&ct"), #ifdef EXPERIMENTAL_EFFECT_MANAGEMENT Command( wxT("ManageEffects"), XXO("Add / Remove Plug-ins..."), FN(OnManageEffects), AudioIONotBusyFlag ), @@ -801,7 +806,7 @@ MenuTable::BaseItemPtr EffectMenu( AudacityProject &project ) EffectTypeProcess, AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag, IsRealtimeNotActiveFlag ) ) - ); + ) ); } MenuTable::BaseItemPtr AnalyzeMenu( AudacityProject & ) @@ -810,7 +815,8 @@ MenuTable::BaseItemPtr AnalyzeMenu( AudacityProject & ) // All of this is a bit hacky until we can get more things connected into // the plugin manager...sorry! :-( - return Menu( XO("&Analyze"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Analyze"), #ifdef EXPERIMENTAL_EFFECT_MANAGEMENT Command( wxT("ManageAnalyzers"), XXO("Add / Remove Plug-ins..."), FN(OnManageAnalyzers), AudioIONotBusyFlag ), @@ -829,7 +835,7 @@ MenuTable::BaseItemPtr AnalyzeMenu( AudacityProject & ) EffectTypeAnalyze, AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag, IsRealtimeNotActiveFlag ) ) - ); + ) ); } MenuTable::BaseItemPtr ToolsMenu( AudacityProject & ) @@ -838,7 +844,8 @@ MenuTable::BaseItemPtr ToolsMenu( AudacityProject & ) using Options = CommandManager::Options; auto gAudioIO = AudioIO::Get(); - return Menu( XO("T&ools"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("T&ools"), #ifdef EXPERIMENTAL_EFFECT_MANAGEMENT Command( wxT("ManageTools"), XXO("Add / Remove Plug-ins..."), @@ -899,7 +906,7 @@ MenuTable::BaseItemPtr ToolsMenu( AudacityProject & ) AudioIONotBusyFlag, Options{}.CheckState( gAudioIO->mDetectUpstreamDropouts ) ) #endif - ); + ) ); } MenuTable::BaseItemPtr ExtraScriptablesIMenu( AudacityProject & ) @@ -907,9 +914,11 @@ MenuTable::BaseItemPtr ExtraScriptablesIMenu( AudacityProject & ) using namespace MenuTable; // These are the more useful to VI user Scriptables. + + return FinderScope( findCommandHandler ).Eval( // i18n-hint: Scriptables are commands normally used from Python, Perl etc. - return Menu( XO("Script&ables I"), - // Note that the PLUGIN_SYMBOL must have a space between words, + Menu( XO("Script&ables I"), + // Note that the PLUGIN_SYMBOL must have a space between words, // whereas the short-form used here must not. // (So if you did write "CompareAudio" for the PLUGIN_SYMBOL name, then // you would have to use "Compareaudio" here.) @@ -945,7 +954,7 @@ MenuTable::BaseItemPtr ExtraScriptablesIMenu( AudacityProject & ) AudioIONotBusyFlag ), Command( wxT("SetProject"), XXO("Set Project..."), FN(OnAudacityCommand), AudioIONotBusyFlag ) - ); + ) ); } MenuTable::BaseItemPtr ExtraScriptablesIIMenu( AudacityProject & ) @@ -953,7 +962,8 @@ MenuTable::BaseItemPtr ExtraScriptablesIIMenu( AudacityProject & ) using namespace MenuTable; // Less useful to VI users. - return Menu( XO("Scripta&bles II"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("Scripta&bles II"), Command( wxT("Select"), XXO("Select..."), FN(OnAudacityCommand), AudioIONotBusyFlag ), Command( wxT("SetTrack"), XXO("Set Track..."), FN(OnAudacityCommand), @@ -983,7 +993,7 @@ MenuTable::BaseItemPtr ExtraScriptablesIIMenu( AudacityProject & ) Command( wxT("Screenshot"), XXO("Screenshot (short format)..."), FN(OnAudacityCommand), AudioIONotBusyFlag ) - ); + ) ); } #undef FN diff --git a/src/menus/SelectMenus.cpp b/src/menus/SelectMenus.cpp index d60d642ee..396119491 100644 --- a/src/menus/SelectMenus.cpp +++ b/src/menus/SelectMenus.cpp @@ -1026,8 +1026,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &project) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& SelectActions::Handler :: X) +#define FN(X) (& SelectActions::Handler :: X) MenuTable::BaseItemPtr ClipSelectMenu( AudacityProject& ); @@ -1035,9 +1034,10 @@ MenuTable::BaseItemPtr SelectMenu( AudacityProject& ) { using namespace MenuTable; using Options = CommandManager::Options; - + + return FinderScope( findCommandHandler ).Eval( /* i18n-hint: (verb) It's an item on a menu. */ - return Menu( XO("&Select"), + Menu( XO("&Select"), Command( wxT("SelectAll"), XXO("&All"), FN(OnSelectAll), TracksExistFlag, Options{ wxT("Ctrl+A"), XO("Select All") } ), @@ -1135,13 +1135,15 @@ MenuTable::BaseItemPtr SelectMenu( AudacityProject& ) Command( wxT("ZeroCross"), XXO("At &Zero Crossings"), FN(OnZeroCrossing), TracksSelectedFlag, Options{ wxT("Z"), XO("Select Zero Crossing") } ) - ); + ) ); } MenuTable::BaseItemPtr ExtraSelectionMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("&Selection"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Selection"), Command( wxT("SnapToOff"), XXO("Snap-To &Off"), FN(OnSnapToOff), AlwaysEnabledFlag ), Command( wxT("SnapToNearest"), XXO("Snap-To &Nearest"), @@ -1174,7 +1176,7 @@ MenuTable::BaseItemPtr ExtraSelectionMenu( AudacityProject & ) FN(OnSelContractRight), TracksExistFlag | TrackPanelHasFocus, wxT("Ctrl+Shift+Left\twantKeyup") ) - ); + ) ); } MenuTable::BaseItemPtr ClipCursorItems( AudacityProject & ); @@ -1190,7 +1192,8 @@ MenuTable::BaseItemPtr CursorMenu( AudacityProject & ) // GA: 'Skip to' moves the viewpoint to center of the track and preserves the // selection. 'Cursor to' does neither. 'Center at' might describe it better // than 'Skip'. - return Menu( XO("&Cursor to"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Cursor to"), Command( wxT("CursSelStart"), XXO("Selection Star&t"), FN(OnCursorSelStart), TimeSelectedFlag, @@ -1218,7 +1221,7 @@ MenuTable::BaseItemPtr CursorMenu( AudacityProject & ) Command( wxT("CursProjectEnd"), XXO("Project E&nd"), FN(OnSkipEnd), CanStopFlags, Options{ wxT("End"), XO("Cursor to Project End") } ) - ); + ) ); } MenuTable::BaseItemPtr ExtraClipCursorItems( AudacityProject & ); @@ -1227,7 +1230,8 @@ MenuTable::BaseItemPtr ExtraCursorMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("&Cursor"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Cursor"), Command( wxT("CursorLeft"), XXO("Cursor &Left"), FN(OnCursorLeft), TracksExistFlag | TrackPanelHasFocus, wxT("Left\twantKeyup\tallowDup") ), @@ -1248,13 +1252,15 @@ MenuTable::BaseItemPtr ExtraCursorMenu( AudacityProject & ) TracksExistFlag | TrackPanelHasFocus, wxT("Shift+.") ), ExtraClipCursorItems - ); + ) ); } MenuTable::BaseItemPtr ExtraSeekMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("See&k"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("See&k"), Command( wxT("SeekLeftShort"), XXO("Short Seek &Left During Playback"), FN(OnSeekLeftShort), AudioIOBusyFlag, wxT("Left\tallowDup") ), Command( wxT("SeekRightShort"), @@ -1264,7 +1270,7 @@ MenuTable::BaseItemPtr ExtraSeekMenu( AudacityProject & ) FN(OnSeekLeftLong), AudioIOBusyFlag, wxT("Shift+Left\tallowDup") ), Command( wxT("SeekRightLong"), XXO("Long Seek Rig&ht During Playback"), FN(OnSeekRightLong), AudioIOBusyFlag, wxT("Shift+Right\tallowDup") ) - ); + ) ); } #undef FN diff --git a/src/menus/ToolbarMenus.cpp b/src/menus/ToolbarMenus.cpp index b2f5fdcb3..d070aaebf 100644 --- a/src/menus/ToolbarMenus.cpp +++ b/src/menus/ToolbarMenus.cpp @@ -251,8 +251,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& ToolbarActions::Handler :: X) +#define FN(X) (& ToolbarActions::Handler :: X) MenuTable::BaseItemPtr ToolbarsMenu( AudacityProject& ) { @@ -261,7 +260,8 @@ MenuTable::BaseItemPtr ToolbarsMenu( AudacityProject& ) static const auto checkOff = Options{}.CheckState( false ); - return Menu( XO("&Toolbars"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Toolbars"), /* i18n-hint: (verb)*/ Command( wxT("ResetToolbars"), XXO("Reset Toolb&ars"), FN(OnResetToolBars), AlwaysEnabledFlag ), @@ -330,13 +330,15 @@ MenuTable::BaseItemPtr ToolbarsMenu( AudacityProject& ) XXO("Spe&ctral Selection Toolbar"), FN(OnShowSpectralSelectionToolBar), AlwaysEnabledFlag, checkOff ) #endif - ); + ) ); } MenuTable::BaseItemPtr ExtraToolsMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("T&ools"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("T&ools"), Command( wxT("SelectTool"), XXO("&Selection Tool"), FN(OnSelectTool), AlwaysEnabledFlag, wxT("F1") ), Command( wxT("EnvelopeTool"), XXO("&Envelope Tool"), @@ -353,7 +355,7 @@ MenuTable::BaseItemPtr ExtraToolsMenu( AudacityProject & ) AlwaysEnabledFlag, wxT("A") ), Command( wxT("NextTool"), XXO("&Next Tool"), FN(OnNextTool), AlwaysEnabledFlag, wxT("D") ) - ); + ) ); } #undef FN diff --git a/src/menus/TrackMenus.cpp b/src/menus/TrackMenus.cpp index 508bc6b53..6e1ddb83b 100644 --- a/src/menus/TrackMenus.cpp +++ b/src/menus/TrackMenus.cpp @@ -1274,16 +1274,16 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& TrackActions::Handler :: X) +#define FN(X) (& TrackActions::Handler :: X) MenuTable::BaseItemPtr TracksMenu( AudacityProject & ) { // Tracks Menu (formerly Project Menu) using namespace MenuTable; using Options = CommandManager::Options; - - return Menu( XO("&Tracks"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Tracks"), Menu( XO("Add &New"), Command( wxT("NewMonoTrack"), XXO("&Mono Track"), FN(OnNewWaveTrack), AudioIONotBusyFlag, wxT("Ctrl+Shift+N") ), @@ -1300,6 +1300,7 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & ) Separator(), Menu( XO("Mi&x"), + // Delayed evaluation // Stereo to Mono is an oddball command that is also subject to control // by the plug-in manager, as if an effect. Decide whether to show or // hide it. @@ -1311,7 +1312,7 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & ) return Command( wxT("Stereo to Mono"), XXO("Mix Stereo Down to &Mono"), FN(OnStereoToMono), AudioIONotBusyFlag | StereoRequiredFlag | - WaveTracksSelectedFlag ); + WaveTracksSelectedFlag, Options{}, findCommandHandler ); else return {}; }, @@ -1427,14 +1428,15 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & ) Options{}.CheckState( gPrefs->Read(wxT("/GUI/SyncLockTracks"), 0L) ) ) #endif - ); + ) ); } MenuTable::BaseItemPtr ExtraTrackMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("&Track"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Track"), Command( wxT("TrackPan"), XXO("Change P&an on Focused Track..."), FN(OnTrackPan), TrackPanelHasFocus | TracksExistFlag, wxT("Shift+P") ), @@ -1478,7 +1480,7 @@ MenuTable::BaseItemPtr ExtraTrackMenu( AudacityProject & ) Command( wxT("TrackMoveBottom"), XXO("Move Focused Track to &Bottom"), FN(OnTrackMoveBottom), AudioIONotBusyFlag | TrackPanelHasFocus | TracksExistFlag ) - ); + ) ); } #undef FN diff --git a/src/menus/TransportMenus.cpp b/src/menus/TransportMenus.cpp index 078da6d42..f0fd9d4c8 100644 --- a/src/menus/TransportMenus.cpp +++ b/src/menus/TransportMenus.cpp @@ -966,8 +966,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& TransportActions::Handler :: X) +#define FN(X) (& TransportActions::Handler :: X) MenuTable::BaseItemPtr CursorMenu( AudacityProject& ); @@ -981,9 +980,10 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project ) static const auto CanStopFlags = AudioIONotBusyFlag | CanStopAudioStreamFlag; + return FinderScope( findCommandHandler ).Eval( /* i18n-hint: 'Transport' is the name given to the set of controls that play, record, pause etc. */ - return Menu( XO("Tra&nsport"), + Menu( XO("Tra&nsport"), Menu( XO("Pl&aying"), /* i18n-hint: (verb) Start or Stop audio playback*/ Command( wxT("PlayStop"), XXO("Pl&ay/Stop"), FN(OnPlayStop), @@ -1085,13 +1085,15 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project ) AudioIONotBusyFlag | CanStopAudioStreamFlag, checkOff ) #endif ) - ); + ) ); } MenuTable::BaseItemPtr ExtraTransportMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("T&ransport"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("T&ransport"), // PlayStop is already in the menus. /* i18n-hint: (verb) Start playing audio*/ Command( wxT("Play"), XXO("Pl&ay"), FN(OnPlayStop), @@ -1133,13 +1135,15 @@ MenuTable::BaseItemPtr ExtraTransportMenu( AudacityProject & ) Command(wxT("KeyboardScrubForwards"), XXO("Scrub For&wards"), FN(OnKeyboardScrubForwards), CaptureNotBusyFlag | CanStopAudioStreamFlag, wxT("I\twantKeyup")) - ); + ) ); } MenuTable::BaseItemPtr ExtraPlayAtSpeedMenu( AudacityProject & ) { using namespace MenuTable; - return Menu( XO("&Play-at-Speed"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Play-at-Speed"), /* i18n-hint: 'Normal Play-at-Speed' doesn't loop or cut preview. */ Command( wxT("PlayAtSpeed"), XXO("Normal Pl&ay-at-Speed"), FN(OnPlayAtSpeed), CaptureNotBusyFlag ), @@ -1163,7 +1167,7 @@ MenuTable::BaseItemPtr ExtraPlayAtSpeedMenu( AudacityProject & ) Command( wxT("MoveToNextLabel"), XXO("Move to &Next Label"), FN(OnMoveToNextLabel), CaptureNotBusyFlag | TrackPanelHasFocus, wxT("Alt+Right") ) - ); + ) ); } #undef FN diff --git a/src/menus/ViewMenus.cpp b/src/menus/ViewMenus.cpp index ab0dbc847..75bb99bdd 100644 --- a/src/menus/ViewMenus.cpp +++ b/src/menus/ViewMenus.cpp @@ -430,8 +430,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &project) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& ViewActions::Handler :: X) +#define FN(X) (& ViewActions::Handler :: X) MenuTable::BaseItemPtr ToolbarsMenu( AudacityProject& ); @@ -442,7 +441,8 @@ MenuTable::BaseItemPtr ViewMenu( AudacityProject& ) static const auto checkOff = Options{}.CheckState( false ); - return Menu( XO("&View"), + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&View"), Menu( XO("&Zoom"), Command( wxT("ZoomIn"), XXO("Zoom &In"), FN(OnZoomIn), ZoomInAvailableFlag, wxT("Ctrl+1") ), @@ -547,7 +547,7 @@ MenuTable::BaseItemPtr ViewMenu( AudacityProject& ) Command( wxT("ShowEffectsRack"), XXO("Show Effects Rack"), FN(OnShowEffectsRack), AlwaysEnabledFlag, checkOff ) #endif - ); + ) ); } #undef FN diff --git a/src/menus/WindowMenus.cpp b/src/menus/WindowMenus.cpp index 1a6d9c761..02ed69a5d 100644 --- a/src/menus/WindowMenus.cpp +++ b/src/menus/WindowMenus.cpp @@ -116,8 +116,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { // Menu definitions -#define FN(X) findCommandHandler, \ - static_cast(& WindowActions::Handler :: X) +#define FN(X) (& WindowActions::Handler :: X) MenuTable::BaseItemPtr WindowMenu( AudacityProject & ) { @@ -125,7 +124,9 @@ MenuTable::BaseItemPtr WindowMenu( AudacityProject & ) // poor imitation of the Mac Windows Menu ////////////////////////////////////////////////////////////////////////// using namespace MenuTable; - return Menu( XO("&Window"), + + return FinderScope( findCommandHandler ).Eval( + Menu( XO("&Window"), /* i18n-hint: Standard Macintosh Window menu item: Make (the current * window) shrink to an icon on the dock */ Command( wxT("MacMinimize"), XXO("&Minimize"), FN(OnMacMinimize), @@ -141,20 +142,21 @@ MenuTable::BaseItemPtr WindowMenu( AudacityProject & ) * windows un-hidden */ Command( wxT("MacBringAllToFront"), XXO("&Bring All to Front"), FN(OnMacBringAllToFront), AlwaysEnabledFlag ) - ); + ) ); } MenuTable::BaseItemPtr ExtraWindowItems( AudacityProject & ) { using namespace MenuTable; - return Items( + return FinderScope( findCommandHandler ).Eval( + Items( /* i18n-hint: Shrink all project windows to icons on the Macintosh tooldock */ Command( wxT("MacMinimizeAll"), XXO("Minimize All Projects"), FN(OnMacMinimizeAll), AlwaysEnabledFlag, wxT("Ctrl+Alt+M") ) - ); + ) ); } #undef FN diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index 0001bcdd2..f6cca411d 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -1121,18 +1121,18 @@ bool Scrubber::CanScrub() const HasWaveDataPred( *mProject ); } -// To supply the "finder" argument -static CommandHandlerObject &findme(AudacityProject &project) -{ return Scrubber::Get( project ); } - MenuTable::BaseItemPtr Scrubber::Menu() { using Options = CommandManager::Options; + auto scope = MenuTable::FinderScope( + [](AudacityProject &project) -> CommandHandlerObject& + { return Scrubber::Get( project ); } ); + MenuTable::BaseItemPtrs ptrs; for (const auto &item : menuItems) { ptrs.push_back( MenuTable::Command( item.name, item.label, - findme, static_cast(item.memFn), + item.memFn, item.flags, item.StatusTest ? // a checkmark item