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 &)=delete
 
MenuManageroperator= (const MenuManager &)=delete
 
 ~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 (MenuTable::Visitor< MenuTable::Traits > &visitor, AudacityProject &project)
 
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 77 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}
const auto project
void OnUndoRedo(struct UndoRedoMessage)
Definition: Menus.cpp:502
void UpdatePrefs() override
Definition: Menus.cpp:91
Observer::Subscription mUndoSubscription
Definition: Menus.h:121
AudacityProject & mProject
Definition: Menus.h:122
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(), project, Observer::Publisher< Message, NotifyAll >::Subscribe(), and UpdatePrefs().

Here is the call graph for this function:

◆ MenuManager() [2/2]

MenuManager::MenuManager ( const MenuManager )
delete

◆ ~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:82

References key, and project.

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(), and project.

Here is the call graph for this function:

◆ GetUpdateFlags()

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

Definition at line 517 of file Menus.cpp.

518{
519 // This method determines all of the flags that determine whether
520 // certain menu items and commands should be enabled or disabled,
521 // and returns them in a bitfield. Note that if none of the flags
522 // have changed, it's not necessary to even check for updates.
523
524 // static variable, used to remember flags for next time.
525 static CommandFlag lastFlags;
526
527 CommandFlag flags, quickFlags;
528
529 const auto &options = ReservedCommandFlag::Options();
530 size_t ii = 0;
531 for ( const auto &predicate : ReservedCommandFlag::RegisteredPredicates() ) {
532 if ( options[ii].quickTest ) {
533 quickFlags[ii] = true;
534 if( predicate( mProject ) )
535 flags[ii] = true;
536 }
537 ++ii;
538 }
539
540 if ( checkActive && !GetProjectFrame( mProject ).IsActive() )
541 // quick 'short-circuit' return.
542 flags = (lastFlags & ~quickFlags) | flags;
543 else {
544 ii = 0;
545 for ( const auto &predicate
547 if ( !options[ii].quickTest && predicate( mProject ) )
548 flags[ii] = true;
549 ++ii;
550 }
551 }
552
553 lastFlags = flags;
554 return flags;
555}
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(), mProject, ReservedCommandFlag::Options(), and ReservedCommandFlag::RegisteredPredicates().

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

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 433 of file Menus.cpp.

434{
436 auto &undoManager = UndoManager::Get( project );
437 auto &commandManager = CommandManager::Get( project );
438 int cur = undoManager.GetCurrentState();
439
440 if (undoManager.UndoAvailable()) {
441 undoManager.GetShortDescription(cur, &desc);
442 commandManager.Modify(wxT("Undo"),
443 XXO("&Undo %s")
444 .Format( desc ));
445 commandManager.Enable(wxT("Undo"),
446 ProjectHistory::Get( project ).UndoAvailable());
447 }
448 else {
449 commandManager.Modify(wxT("Undo"),
450 XXO("&Undo"));
451 }
452
453 if (undoManager.RedoAvailable()) {
454 undoManager.GetShortDescription(cur+1, &desc);
455 commandManager.Modify(wxT("Redo"),
456 XXO("&Redo %s")
457 .Format( desc ));
458 commandManager.Enable(wxT("Redo"),
459 ProjectHistory::Get( project ).RedoAvailable());
460 }
461 else {
462 commandManager.Modify(wxT("Redo"),
463 XXO("&Redo"));
464 commandManager.Enable(wxT("Redo"), false);
465 }
466}
wxT("CloseDown"))
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.
const TranslatableString desc
Definition: ExportPCM.cpp:51

References anonymous_namespace{ExportPCM.cpp}::desc, ProjectHistory::Get(), UndoManager::Get(), CommandManager::Get(), project, wxT(), and XXO().

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

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 502 of file Menus.cpp.

503{
504 switch (message.type) {
509 break;
510 default:
511 return;
512 }
514 UpdateMenus();
515}
static void ModifyUndoMenuItems(AudacityProject &project)
Definition: Menus.cpp:433
void UpdateMenus(bool checkActive=true)
Definition: Menus.cpp:559
enum UndoRedoMessage::Type type

References ModifyUndoMenuItems(), mProject, UndoRedoMessage::Pushed, UndoRedoMessage::Renamed, UndoRedoMessage::Reset, UndoRedoMessage::type, UndoRedoMessage::UndoOrRedo, and UpdateMenus().

Referenced by MenuManager().

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

◆ operator=()

MenuManager & MenuManager::operator= ( const MenuManager )
delete

◆ ReportIfActionNotAllowed()

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

Definition at line 621 of file Menus.cpp.

623{
624 auto &project = mProject;
625 bool bAllowed = TryToMakeActionAllowed( flags, flagsRqd );
626 if( bAllowed )
627 return true;
628 auto &cm = CommandManager::Get( project );
629 TellUserWhyDisallowed( Name, flags & flagsRqd, flagsRqd);
630 return false;
631}
bool TryToMakeActionAllowed(CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:636
void TellUserWhyDisallowed(const TranslatableString &Name, CommandFlag flagsGot, CommandFlag flagsRequired)
Definition: Menus.cpp:667

References CommandManager::Get(), mProject, project, TellUserWhyDisallowed(), and TryToMakeActionAllowed().

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 667 of file Menus.cpp.

669{
670 // The default string for 'reason' is a catch all. I hope it won't ever be seen
671 // and that we will get something more specific.
672 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.");
673 // The default title string is 'Disallowed'.
674 auto untranslatedTitle = XO("Disallowed");
675 wxString helpPage;
676
677 bool enableDefaultMessage = true;
678 bool defaultMessage = true;
679
680 auto doOption = [&](const CommandFlagOptions &options) {
681 if ( options.message ) {
682 reason = options.message( Name );
683 defaultMessage = false;
684 if ( !options.title.empty() )
685 untranslatedTitle = options.title;
686 helpPage = options.helpPage;
687 return true;
688 }
689 else {
690 enableDefaultMessage =
691 enableDefaultMessage && options.enableDefaultMessage;
692 return false;
693 }
694 };
695
696 const auto &alloptions = ReservedCommandFlag::Options();
697 auto missingFlags = flagsRequired & ~flagsGot;
698
699 // Find greatest priority
700 unsigned priority = 0;
701 for ( const auto &options : alloptions )
702 priority = std::max( priority, options.priority );
703
704 // Visit all unsatisfied conditions' options, by descending priority,
705 // stopping when we find a message
706 ++priority;
707 while( priority-- ) {
708 size_t ii = 0;
709 for ( const auto &options : alloptions ) {
710 if (
711 priority == options.priority
712 &&
713 missingFlags[ii]
714 &&
715 doOption( options ) )
716 goto done;
717
718 ++ii;
719 }
720 }
721 done:
722
723 if (
724 // didn't find a message
725 defaultMessage
726 &&
727 // did find a condition that suppresses the default message
728 !enableDefaultMessage
729 )
730 return;
731
732 // Does not have the warning icon...
734 untranslatedTitle,
735 reason,
736 helpPage);
737}
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:260

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

Referenced by ReportIfActionNotAllowed().

Here is the call graph for this function:
Here is the caller 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 636 of file Menus.cpp.

638{
639 auto &project = mProject;
640
641 if( flags.none() )
642 flags = GetUpdateFlags();
643
644 // Visit the table of recovery actions
645 auto &enablers = RegisteredMenuItemEnabler::Enablers();
646 auto iter = enablers.begin(), end = enablers.end();
647 while ((flags & flagsRqd) != flagsRqd && iter != end) {
648 const auto &enabler = *iter;
649 auto actual = enabler.actualFlags();
650 auto MissingFlags = (~flags & flagsRqd);
651 if (
652 // Do we have the right precondition?
653 (flags & actual) == actual
654 &&
655 // Can we get the condition we need?
656 (MissingFlags & enabler.possibleFlags()).any()
657 ) {
658 // Then try the function
659 enabler.tryEnable( project, flagsRqd );
660 flags = GetUpdateFlags();
661 }
662 ++iter;
663 }
664 return (flags & flagsRqd) == flagsRqd;
665}
CommandFlag GetUpdateFlags(bool checkActive=false) const
Definition: Menus.cpp:517
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(), PackedArray::end(), GetUpdateFlags(), mProject, and project.

Referenced by ProjectAudioManager::DoRecord(), and ReportIfActionNotAllowed().

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 559 of file Menus.cpp.

560{
561 auto &project = mProject;
562
563 auto flags = GetUpdateFlags(checkActive);
564 // Return from this function if nothing's changed since
565 // the last time we were here.
566 if (flags == mLastFlags)
567 return;
568 mLastFlags = flags;
569
570 auto flags2 = flags;
571
572 // We can enable some extra items if we have select-all-on-none.
573 //EXPLAIN-ME: Why is this here rather than in GetUpdateFlags()?
574 //ANSWER: Because flags2 is used in the menu enable/disable.
575 //The effect still needs flags to determine whether it will need
576 //to actually do the 'select all' to make the command valid.
577
578 for ( const auto &enabler : RegisteredMenuItemEnabler::Enablers() ) {
579 auto actual = enabler.actualFlags();
580 if (
581 enabler.applicable( project ) && (flags & actual) == actual
582 )
583 flags2 |= enabler.possibleFlags();
584 }
585
586 auto &commandManager = CommandManager::Get( project );
587
588 // With select-all-on-none, some items that we don't want enabled may have
589 // been enabled, since we changed the flags. Here we manually disable them.
590 // 0 is grey out, 1 is Autoselect, 2 is Give warnings.
591 commandManager.EnableUsingFlags(
592 flags2, // the "lax" flags
593 (mWhatIfNoSelection == 0 ? flags2 : flags) // the "strict" flags
594 );
595
596 Publish({});
597}
CommandFlag mLastFlags
Definition: Menus.h:51
int mWhatIfNoSelection
Definition: Menus.h:126
CallbackReturn Publish(const MenuUpdateMessage &message)
Send a message to connected callbacks.
Definition: Observer.h:207

References RegisteredMenuItemEnabler::Enablers(), CommandManager::Get(), GetUpdateFlags(), MenuCreator::mLastFlags, mProject, mWhatIfNoSelection, project, and Observer::Publisher< MenuUpdateMessage >::Publish().

Referenced by MacroCommands::ApplyCommandInBatchMode(), EffectUI::DoEffect(), ProjectWindow::FixScrollbars(), OnUndoRedo(), 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}
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
bool mStopIfWasPaused
Definition: Menus.h:127
virtual bool Read(const wxString &key, bool *value) const =0

References gPrefs, mStopIfWasPaused, mWhatIfNoSelection, audacity::BasicSettings::Read(), 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 ( MenuTable::Visitor< MenuTable::Traits > &  visitor,
AudacityProject project 
)
static

Definition at line 422 of file Menus.cpp.

424{
425 static const auto menuTree = MenuTable::Items( MenuPathStart );
426
427 wxLogNull nolog;
428 Registry::VisitWithFunctions(visitor, menuTree.get(),
430}
static const auto MenuPathStart
constexpr auto Items
void VisitWithFunctions(const VisitorFunctions< RegistryTraits > &visitors, const GroupItem< RegistryTraits > *pTopItem, const GroupItem< RegistryTraits > *pRegistry={}, typename RegistryTraits::ComputedItemContextType &computedItemContext=RegistryTraits::ComputedItemContextType::Instance)
Definition: Registry.h:623
static GroupItem< Traits > & Registry()
Definition: Menus.cpp:271

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

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

◆ mStopIfWasPaused

bool MenuManager::mStopIfWasPaused

Definition at line 127 of file Menus.h.

Referenced by UpdatePrefs().

◆ mUndoSubscription

Observer::Subscription MenuManager::mUndoSubscription
private

Definition at line 121 of file Menus.h.

Referenced by MenuManager().

◆ mWhatIfNoSelection

int MenuManager::mWhatIfNoSelection

Definition at line 126 of file Menus.h.

Referenced by UpdateMenus(), and UpdatePrefs().


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