Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
MenuManager Class Referencefinal

MenuManager handles updates to menu state. More...

#include <Menus.h>

Inheritance diagram for MenuManager:
[legend]
Collaboration diagram for MenuManager:
[legend]

Public Member Functions

 MenuManager (AudacityProject &project)
 
 MenuManager (const MenuManager &) PROHIBITED
 
MenuManageroperator= (const MenuManager &) PROHIBITED
 
 ~MenuManager ()
 
void UpdateMenus (bool checkActive=true)
 
CommandFlag GetUpdateFlags (bool checkActive=false) const
 
void UpdatePrefs () override
 
bool ReportIfActionNotAllowed (const TranslatableString &Name, CommandFlag &flags, CommandFlag flagsRqd)
 
bool TryToMakeActionAllowed (CommandFlag &flags, CommandFlag flagsRqd)
 
- Public Member Functions inherited from MenuCreator
 MenuCreator ()
 
 ~MenuCreator ()
 
void CreateMenusAndCommands (AudacityProject &project)
 
void RebuildMenuBar (AudacityProject &project)
 
- Public Member Functions inherited from ClientData::Base
virtual ~Base ()
 
- Public Member Functions inherited from Observer::Publisher< MenuUpdateMessage >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 

Static Public Member Functions

static MenuManagerGet (AudacityProject &project)
 
static const MenuManagerGet (const AudacityProject &project)
 
static void Visit (ToolbarMenuVisitor &visitor)
 
static void ModifyUndoMenuItems (AudacityProject &project)
 
- Static Public Member Functions inherited from MenuCreator
static void RebuildAllMenuBars ()
 

Public Attributes

int mWhatIfNoSelection
 
bool mStopIfWasPaused
 
- Public Attributes inherited from MenuCreator
CommandFlag mLastFlags
 
PluginID mLastGenerator {}
 
PluginID mLastEffect {}
 
PluginID mLastAnalyzer {}
 
int mLastAnalyzerRegistration
 
int mLastAnalyzerRegisteredId
 
PluginID mLastTool {}
 
int mLastToolRegistration
 
int mLastToolRegisteredId
 
unsigned mRepeatGeneratorFlags
 
unsigned mRepeatEffectFlags
 
unsigned mRepeatAnalyzerFlags
 
unsigned mRepeatToolFlags
 

Private Member Functions

void TellUserWhyDisallowed (const TranslatableString &Name, CommandFlag flagsGot, CommandFlag flagsRequired)
 
void OnUndoRedo (struct UndoRedoMessage)
 
- Private Member Functions inherited from PrefsListener
 PrefsListener ()
 
virtual ~PrefsListener ()
 
virtual void UpdatePrefs ()=0
 
virtual void UpdateSelectedPrefs (int id)
 

Private Attributes

Observer::Subscription mUndoSubscription
 
AudacityProjectmProject
 

Additional Inherited Members

- Public Types inherited from MenuCreator
enum  { repeattypenone = 0 , repeattypeplugin = 1 , repeattypeunique = 2 , repeattypeapplymacro = 3 }
 
- Public Types inherited from Observer::Publisher< MenuUpdateMessage >
using message_type = MenuUpdateMessage
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const MenuUpdateMessage &) >
 Type of functions that can be connected to the Publisher. More...
 
- Static Public Attributes inherited from Observer::Publisher< MenuUpdateMessage >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from Observer::Publisher< MenuUpdateMessage >
CallbackReturn Publish (const MenuUpdateMessage &message)
 Send a message to connected callbacks. More...
 
- Static Private Member Functions inherited from PrefsListener
static void Broadcast (int id=0)
 Call this static function to notify all PrefsListener objects. More...
 

Detailed Description

MenuManager handles updates to menu state.

Definition at line 76 of file Menus.h.

Constructor & Destructor Documentation

◆ MenuManager() [1/2]

MenuManager::MenuManager ( AudacityProject project)
explicit

Definition at line 79 of file Menus.cpp.

80 : mProject{ project }
81{
85}
void OnUndoRedo(struct UndoRedoMessage)
Definition: Menus.cpp:520
void UpdatePrefs() override
Definition: Menus.cpp:91
Observer::Subscription mUndoSubscription
Definition: Menus.h:119
AudacityProject & mProject
Definition: Menus.h:120
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:71

References UndoManager::Get(), mUndoSubscription, OnUndoRedo(), Observer::Publisher< Message, NotifyAll >::Subscribe(), and UpdatePrefs().

Here is the call graph for this function:

◆ MenuManager() [2/2]

MenuManager::MenuManager ( const MenuManager )

◆ ~MenuManager()

MenuManager::~MenuManager ( )

Definition at line 87 of file Menus.cpp.

88{
89}

Member Function Documentation

◆ Get() [1/2]

MenuManager & MenuManager::Get ( AudacityProject project)
static

Definition at line 69 of file Menus.cpp.

70{
71 return project.AttachedObjects::Get< MenuManager >( key );
72}
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: Menus.cpp:64
MenuManager handles updates to menu state.
Definition: Menus.h:81

References key.

Referenced by anonymous_namespace{PluginMenus.cpp}::AnalyzeMenu(), MacroCommands::ApplyCommandInBatchMode(), ToolManager::CreateWindows(), CommonTrackPanelCell::DoContextMenu(), EffectUI::DoEffect(), ProjectAudioManager::DoRecord(), DoReloadPreferences(), anonymous_namespace{PluginMenus.cpp}::EffectMenu(), CommandManager::FilterKeyEvent(), ProjectWindow::FixScrollbars(), anonymous_namespace{PluginMenus.cpp}::GenerateMenu(), Get(), CommandManager::HandleCommandEntry(), anonymous_namespace{PluginMenus.cpp}::HasLastAnalyzerFlag(), anonymous_namespace{PluginMenus.cpp}::HasLastEffectFlag(), anonymous_namespace{PluginMenus.cpp}::HasLastGeneratorFlag(), anonymous_namespace{BatchProcessDialog.cpp}::HasLastToolFlag(), ProjectManager::New(), EffectUIHost::OnApply(), anonymous_namespace{BatchProcessDialog.cpp}::OnApplyMacroDirectlyByName(), ToolBarButtons::OnButton(), ProjectWindow::OnMenu(), anonymous_namespace{EditMenus.cpp}::OnPreferences(), anonymous_namespace{PluginMenus.cpp}::OnRepeatLastAnalyzer(), anonymous_namespace{PluginMenus.cpp}::OnRepeatLastEffect(), anonymous_namespace{PluginMenus.cpp}::OnRepeatLastGenerator(), anonymous_namespace{BatchProcessDialog.cpp}::OnRepeatLastTool(), anonymous_namespace{PluginMenus.cpp}::OnResetConfig(), ProjectWindow::OnUpdateUI(), PluginMenuItems(), MenuCreator::RebuildAllMenuBars(), CommandManager::RegisterLastAnalyzer(), CommandManager::RegisterLastTool(), SelectUtilities::SelectAllIfNone(), SelectUtilities::SelectAllIfNoneAndAllowed(), and MacrosWindow::UpdateMenus().

Here is the caller graph for this function:

◆ Get() [2/2]

const MenuManager & MenuManager::Get ( const AudacityProject project)
static

Definition at line 74 of file Menus.cpp.

75{
76 return Get( const_cast< AudacityProject & >( project ) );
77}
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:69

References Get().

Here is the call graph for this function:

◆ GetUpdateFlags()

CommandFlag MenuManager::GetUpdateFlags ( bool  checkActive = false) const

Definition at line 535 of file Menus.cpp.

536{
537 // This method determines all of the flags that determine whether
538 // certain menu items and commands should be enabled or disabled,
539 // and returns them in a bitfield. Note that if none of the flags
540 // have changed, it's not necessary to even check for updates.
541
542 // static variable, used to remember flags for next time.
543 static CommandFlag lastFlags;
544
545 CommandFlag flags, quickFlags;
546
547 const auto &options = ReservedCommandFlag::Options();
548 size_t ii = 0;
549 for ( const auto &predicate : ReservedCommandFlag::RegisteredPredicates() ) {
550 if ( options[ii].quickTest ) {
551 quickFlags[ii] = true;
552 if( predicate( mProject ) )
553 flags[ii] = true;
554 }
555 ++ii;
556 }
557
558 if ( checkActive && !GetProjectFrame( mProject ).IsActive() )
559 // quick 'short-circuit' return.
560 flags = (lastFlags & ~quickFlags) | flags;
561 else {
562 ii = 0;
563 for ( const auto &predicate
565 if ( !options[ii].quickTest && predicate( mProject ) )
566 flags[ii] = true;
567 ++ii;
568 }
569 }
570
571 lastFlags = flags;
572 return flags;
573}
std::bitset< NCommandFlags > CommandFlag
Definition: CommandFlag.h:30
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
static const Predicates & RegisteredPredicates()
Definition: CommandFlag.cpp:27
static const std::vector< CommandFlagOptions > & Options()
Definition: CommandFlag.cpp:32

References GetProjectFrame(), ReservedCommandFlag::Options(), and ReservedCommandFlag::RegisteredPredicates().

Referenced by CommonTrackPanelCell::DoContextMenu(), CommandManager::FilterKeyEvent(), ToolBarButtons::OnButton(), ProjectWindow::OnMenu(), SelectUtilities::SelectAllIfNone(), and SelectUtilities::SelectAllIfNoneAndAllowed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ModifyUndoMenuItems()

void MenuManager::ModifyUndoMenuItems ( AudacityProject project)
static

Definition at line 451 of file Menus.cpp.

452{
454 auto &undoManager = UndoManager::Get( project );
455 auto &commandManager = CommandManager::Get( project );
456 int cur = undoManager.GetCurrentState();
457
458 if (undoManager.UndoAvailable()) {
459 undoManager.GetShortDescription(cur, &desc);
460 commandManager.Modify(wxT("Undo"),
461 XXO("&Undo %s")
462 .Format( desc ));
463 commandManager.Enable(wxT("Undo"),
464 ProjectHistory::Get( project ).UndoAvailable());
465 }
466 else {
467 commandManager.Modify(wxT("Undo"),
468 XXO("&Undo"));
469 }
470
471 if (undoManager.RedoAvailable()) {
472 undoManager.GetShortDescription(cur+1, &desc);
473 commandManager.Modify(wxT("Redo"),
474 XXO("&Redo %s")
475 .Format( desc ));
476 commandManager.Enable(wxT("Redo"),
477 ProjectHistory::Get( project ).RedoAvailable());
478 }
479 else {
480 commandManager.Modify(wxT("Redo"),
481 XXO("&Redo"));
482 commandManager.Enable(wxT("Redo"), false);
483 }
484}
wxT("CloseDown"))
const TranslatableString desc
Definition: ExportPCM.cpp:55
XXO("&Cut/Copy/Paste Toolbar")
static CommandManager & Get(AudacityProject &project)
Abstract base class used in importing a file.
static ProjectHistory & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.

References desc, ProjectHistory::Get(), UndoManager::Get(), CommandManager::Get(), wxT(), and XXO().

Referenced by anonymous_namespace{EditMenus.cpp}::EditMenu(), and anonymous_namespace{BatchProcessDialog.cpp}::OnApplyMacroDirectlyByName().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnUndoRedo()

void MenuManager::OnUndoRedo ( struct UndoRedoMessage  message)
private

Definition at line 520 of file Menus.cpp.

521{
522 switch (message.type) {
527 break;
528 default:
529 return;
530 }
532 UpdateMenus();
533}
static void ModifyUndoMenuItems(AudacityProject &project)
Definition: Menus.cpp:451
void UpdateMenus(bool checkActive=true)
Definition: Menus.cpp:577
enum UndoRedoMessage::Type type

References UndoRedoMessage::Pushed, UndoRedoMessage::Renamed, UndoRedoMessage::Reset, UndoRedoMessage::type, and UndoRedoMessage::UndoOrRedo.

Referenced by MenuManager().

Here is the caller graph for this function:

◆ operator=()

MenuManager & MenuManager::operator= ( const MenuManager )

◆ ReportIfActionNotAllowed()

bool MenuManager::ReportIfActionNotAllowed ( const TranslatableString Name,
CommandFlag flags,
CommandFlag  flagsRqd 
)

Definition at line 639 of file Menus.cpp.

641{
642 auto &project = mProject;
643 bool bAllowed = TryToMakeActionAllowed( flags, flagsRqd );
644 if( bAllowed )
645 return true;
646 auto &cm = CommandManager::Get( project );
647 TellUserWhyDisallowed( Name, flags & flagsRqd, flagsRqd);
648 return false;
649}
bool TryToMakeActionAllowed(CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:654
void TellUserWhyDisallowed(const TranslatableString &Name, CommandFlag flagsGot, CommandFlag flagsRequired)
Definition: Menus.cpp:685

References CommandManager::Get().

Referenced by CommandManager::HandleCommandEntry(), and EffectUIHost::OnApply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TellUserWhyDisallowed()

void MenuManager::TellUserWhyDisallowed ( const TranslatableString Name,
CommandFlag  flagsGot,
CommandFlag  flagsRequired 
)
private

Definition at line 685 of file Menus.cpp.

687{
688 // The default string for 'reason' is a catch all. I hope it won't ever be seen
689 // and that we will get something more specific.
690 auto reason = XO("There was a problem with your last action. If you think\nthis is a bug, please tell us exactly where it occurred.");
691 // The default title string is 'Disallowed'.
692 auto untranslatedTitle = XO("Disallowed");
693 wxString helpPage;
694
695 bool enableDefaultMessage = true;
696 bool defaultMessage = true;
697
698 auto doOption = [&](const CommandFlagOptions &options) {
699 if ( options.message ) {
700 reason = options.message( Name );
701 defaultMessage = false;
702 if ( !options.title.empty() )
703 untranslatedTitle = options.title;
704 helpPage = options.helpPage;
705 return true;
706 }
707 else {
708 enableDefaultMessage =
709 enableDefaultMessage && options.enableDefaultMessage;
710 return false;
711 }
712 };
713
714 const auto &alloptions = ReservedCommandFlag::Options();
715 auto missingFlags = flagsRequired & ~flagsGot;
716
717 // Find greatest priority
718 unsigned priority = 0;
719 for ( const auto &options : alloptions )
720 priority = std::max( priority, options.priority );
721
722 // Visit all unsatisfied conditions' options, by descending priority,
723 // stopping when we find a message
724 ++priority;
725 while( priority-- ) {
726 size_t ii = 0;
727 for ( const auto &options : alloptions ) {
728 if (
729 priority == options.priority
730 &&
731 missingFlags[ii]
732 &&
733 doOption( options ) )
734 goto done;
735
736 ++ii;
737 }
738 }
739 done:
740
741 if (
742 // didn't find a message
743 defaultMessage
744 &&
745 // did find a condition that suppresses the default message
746 !enableDefaultMessage
747 )
748 return;
749
750 // Does not have the warning icon...
752 untranslatedTitle,
753 reason,
754 helpPage);
755}
XO("Cut/Copy/Paste")
void ShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options={})
Show an error dialog with a link to the manual for further help.
Definition: BasicUI.h:259

References ReservedCommandFlag::Options(), BasicUI::ShowErrorDialog(), and XO().

Here is the call graph for this function:

◆ TryToMakeActionAllowed()

bool MenuManager::TryToMakeActionAllowed ( CommandFlag flags,
CommandFlag  flagsRqd 
)

Determines if flags for command are compatible with current state. If not, then try some recovery action to make it so.

Returns
whether compatible or not after any actions taken.

Definition at line 654 of file Menus.cpp.

656{
657 auto &project = mProject;
658
659 if( flags.none() )
660 flags = GetUpdateFlags();
661
662 // Visit the table of recovery actions
663 auto &enablers = RegisteredMenuItemEnabler::Enablers();
664 auto iter = enablers.begin(), end = enablers.end();
665 while ((flags & flagsRqd) != flagsRqd && iter != end) {
666 const auto &enabler = *iter;
667 auto actual = enabler.actualFlags();
668 auto MissingFlags = (~flags & flagsRqd);
669 if (
670 // Do we have the right precondition?
671 (flags & actual) == actual
672 &&
673 // Can we get the condition we need?
674 (MissingFlags & enabler.possibleFlags()).any()
675 ) {
676 // Then try the function
677 enabler.tryEnable( project, flagsRqd );
678 flags = GetUpdateFlags();
679 }
680 ++iter;
681 }
682 return (flags & flagsRqd) == flagsRqd;
683}
CommandFlag GetUpdateFlags(bool checkActive=false) const
Definition: Menus.cpp:535
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
static const MenuItemEnablers & Enablers()
Definition: CommandFlag.cpp:56

References RegisteredMenuItemEnabler::Enablers(), and PackedArray::end().

Referenced by ProjectAudioManager::DoRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateMenus()

void MenuManager::UpdateMenus ( bool  checkActive = true)

Definition at line 577 of file Menus.cpp.

578{
579 auto &project = mProject;
580
581 auto flags = GetUpdateFlags(checkActive);
582 // Return from this function if nothing's changed since
583 // the last time we were here.
584 if (flags == mLastFlags)
585 return;
586 mLastFlags = flags;
587
588 auto flags2 = flags;
589
590 // We can enable some extra items if we have select-all-on-none.
591 //EXPLAIN-ME: Why is this here rather than in GetUpdateFlags()?
592 //ANSWER: Because flags2 is used in the menu enable/disable.
593 //The effect still needs flags to determine whether it will need
594 //to actually do the 'select all' to make the command valid.
595
596 for ( const auto &enabler : RegisteredMenuItemEnabler::Enablers() ) {
597 auto actual = enabler.actualFlags();
598 if (
599 enabler.applicable( project ) && (flags & actual) == actual
600 )
601 flags2 |= enabler.possibleFlags();
602 }
603
604 auto &commandManager = CommandManager::Get( project );
605
606 // With select-all-on-none, some items that we don't want enabled may have
607 // been enabled, since we changed the flags. Here we manually disable them.
608 // 0 is grey out, 1 is Autoselect, 2 is Give warnings.
609 commandManager.EnableUsingFlags(
610 flags2, // the "lax" flags
611 (mWhatIfNoSelection == 0 ? flags2 : flags) // the "strict" flags
612 );
613
614 Publish({});
615}
CommandFlag mLastFlags
Definition: Menus.h:48
int mWhatIfNoSelection
Definition: Menus.h:124
CallbackReturn Publish(const MenuUpdateMessage &message)
Send a message to connected callbacks.
Definition: Observer.h:207

References RegisteredMenuItemEnabler::Enablers(), and CommandManager::Get().

Referenced by MacroCommands::ApplyCommandInBatchMode(), EffectUI::DoEffect(), ProjectWindow::FixScrollbars(), and ProjectWindow::OnUpdateUI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdatePrefs()

void MenuManager::UpdatePrefs ( )
overridevirtual

Implements PrefsListener.

Definition at line 91 of file Menus.cpp.

92{
93 bool bSelectAllIfNone;
94 gPrefs->Read(wxT("/GUI/SelectAllOnNone"), &bSelectAllIfNone, false);
95 // 0 is grey out, 1 is Autoselect, 2 is Give warnings.
96#ifdef EXPERIMENTAL_DA
97 // DA warns or greys out.
98 mWhatIfNoSelection = bSelectAllIfNone ? 2 : 0;
99#else
100 // Audacity autoselects or warns.
101 mWhatIfNoSelection = bSelectAllIfNone ? 1 : 2;
102#endif
103 mStopIfWasPaused = true; // not configurable for now, but could be later.
104}
FileConfig * gPrefs
Definition: Prefs.cpp:70
bool mStopIfWasPaused
Definition: Menus.h:125

References gPrefs, mStopIfWasPaused, mWhatIfNoSelection, and wxT().

Referenced by MenuManager().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Visit()

void MenuManager::Visit ( ToolbarMenuVisitor visitor)
static

Definition at line 441 of file Menus.cpp.

442{
443 static const auto menuTree = MenuTable::Items( MenuPathStart );
444
445 wxLogNull nolog;
446 Registry::Visit( visitor, menuTree.get(),
448}
static const auto MenuPathStart
std::unique_ptr< MenuItems > Items(const Identifier &internalName, Args &&... args)
void Visit(Visitor &visitor, BaseItem *pTopItem, const GroupItem *pRegistry)
Definition: Registry.cpp:713
static GroupItem & Registry()
Definition: Menus.cpp:254

References MenuTable::Items(), MenuPathStart, MenuTable::ItemRegistry::Registry(), and Registry::Visit().

Referenced by MenuCreator::CreateMenusAndCommands(), and anonymous_namespace{HelpMenus.cpp}::OnMenuTree().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mProject

AudacityProject& MenuManager::mProject
private

Definition at line 120 of file Menus.h.

◆ mStopIfWasPaused

bool MenuManager::mStopIfWasPaused

Definition at line 125 of file Menus.h.

Referenced by UpdatePrefs().

◆ mUndoSubscription

Observer::Subscription MenuManager::mUndoSubscription
private

Definition at line 119 of file Menus.h.

Referenced by MenuManager().

◆ mWhatIfNoSelection

int MenuManager::mWhatIfNoSelection

Definition at line 124 of file Menus.h.

Referenced by UpdatePrefs().


The documentation for this class was generated from the following files: