Audacity 3.2.0
Menus.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Menus.cpp
6
7 Dominic Mazzoni
8 Brian Gunlogson
9 et al.
10
11*******************************************************************//****************************************************************//****************************************************************//*******************************************************************/
27
28
29#include "Menus.h"
30
31
32
33#include <wx/frame.h>
34
35#include "Project.h"
36#include "ProjectHistory.h"
37#include "ProjectSettings.h"
38#include "ProjectWindows.h"
39#include "UndoManager.h"
43#include "BasicUI.h"
44
45#include <unordered_set>
46
47#include <wx/menu.h>
48#include <wx/windowptr.h>
49#include <wx/log.h>
50
52{
55
60}
61
63{
64}
65
67 []( AudacityProject &project ){
68 return std::make_shared< MenuManager >( project ); }
69};
70
72{
73 return project.AttachedObjects::Get< MenuManager >( key );
74}
75
77{
78 return Get( const_cast< AudacityProject & >( project ) );
79}
80
82 : mProject{ project }
83{
87}
88
90{
91}
92
94{
95 bool bSelectAllIfNone;
96 gPrefs->Read(wxT("/GUI/SelectAllOnNone"), &bSelectAllIfNone, false);
97 // 0 is grey out, 1 is Autoselect, 2 is Give warnings.
98#ifdef EXPERIMENTAL_DA
99 // DA warns or greys out.
100 mWhatIfNoSelection = bSelectAllIfNone ? 2 : 0;
101#else
102 // Audacity autoselects or warns.
103 mWhatIfNoSelection = bSelectAllIfNone ? 1 : 2;
104#endif
105 mStopIfWasPaused = true; // not configurable for now, but could be later.
106}
107
109{
110 bool isMenu = false;
111 bool isExtension = false;
112 auto pItem = &item;
113 if ( pItem->Transparent() ) {
114 }
115 else if ( dynamic_cast<MenuTable::MenuSection*>( pItem ) ) {
116 if ( !needSeparator.empty() )
117 needSeparator.back() = true;
118 }
119 else if ( auto pWhole = dynamic_cast<MenuTable::WholeMenu*>( pItem ) ) {
120 isMenu = true;
121 isExtension = pWhole->extension;
123 }
124
125 DoBeginGroup( item, path );
126
127 if ( isMenu ) {
128 needSeparator.push_back( false );
129 firstItem.push_back( !isExtension );
130 }
131}
132
134{
135 auto pItem = &item;
136 if ( pItem->Transparent() ) {
137 }
138 else if ( dynamic_cast<MenuTable::MenuSection*>( pItem ) ) {
139 if ( !needSeparator.empty() )
140 needSeparator.back() = true;
141 }
142 else if ( dynamic_cast<MenuTable::WholeMenu*>( pItem ) ) {
143 firstItem.pop_back();
144 needSeparator.pop_back();
145 }
146
147 DoEndGroup( item, path );
148}
149
151{
153 DoVisit( item, path );
154}
155
157{
158 bool separate = false;
159 if ( !needSeparator.empty() ) {
160 separate = needSeparator.back() && !firstItem.back();
161 needSeparator.back() = false;
162 firstItem.back() = false;
163 }
164
165 if ( separate )
166 DoSeparator();
167}
168
170{
171}
172
174{
175}
176
178{
179}
180
182{
183}
184
185namespace MenuTable {
186
187MenuItem::MenuItem( const Identifier &internalName,
188 const TranslatableString &title_, BaseItemPtrs &&items_ )
190 internalName, std::move( items_ ) }, title{ title_ }
191{
192 wxASSERT( !title.empty() );
193}
195
197 const Identifier &internalName, Condition condition_, BaseItemPtrs &&items_ )
199 internalName, std::move( items_ ) }, condition{ condition_ }
200{
201}
203
205 const TranslatableString &label_in_,
206 CommandFunctorPointer callback_,
207 CommandFlag flags_,
208 const CommandManager::Options &options_,
209 CommandHandlerFinder finder_)
210: SingleItem{ name_ }, label_in{ label_in_ }
211, finder{ finder_ }, callback{ callback_ }
212, flags{ flags_ }, options{ options_ }
213{}
215
217 std::vector< ComponentInterfaceSymbol > items_,
218 CommandFunctorPointer callback_,
219 CommandFlag flags_,
220 bool isEffect_,
221 CommandHandlerFinder finder_)
222: SingleItem{ name_ }, items{ std::move(items_) }
223, finder{ finder_ }, callback{ callback_ }
224, flags{ flags_ }, isEffect{ isEffect_ }
225{}
227
229
232
234 [](AudacityProject &project) -> CommandHandlerObject & {
235 // If this default finder function is reached, then FinderScope should
236 // have been used somewhere, or an explicit CommandHandlerFinder passed
237 // to menu item constructors
238 wxASSERT( false );
239 return project;
240 };
241
242}
243
247
248namespace {
249
250using namespace Registry;
251
252const auto MenuPathStart = wxT("MenuBar");
253
255{
257 return registry;
258}
259}
260
262 const Placement &placement, BaseItemPtr pItem )
263{
264 Registry::RegisterItem( sRegistry(), placement, std::move( pItem ) );
265}
266
268{
269 sRegistry().items.clear();
270}
271
272namespace {
273
274using namespace MenuTable;
275
277{
279 : ToolbarMenuVisitor(proj), manager( man ) {}
280
281 void DoBeginGroup( GroupItem &item, const Path& ) override
282 {
283 auto pItem = &item;
284 if (const auto pMenu =
285 dynamic_cast<MenuItem*>( pItem )) {
286 manager.BeginMenu( pMenu->title );
287 }
288 else
289 if (const auto pConditionalGroup =
290 dynamic_cast<ConditionalGroupItem*>( pItem )) {
291 const auto flag = pConditionalGroup->condition();
292 if (!flag)
293 manager.BeginOccultCommands();
294 // to avoid repeated call of condition predicate in EndGroup():
295 flags.push_back(flag);
296 }
297 else
298 if ( pItem->Transparent() ) {
299 }
300 else
301 if ( const auto pGroup = dynamic_cast<MenuSection*>( pItem ) ) {
302 }
303 else
304 wxASSERT( false );
305 }
306
307 void DoEndGroup( GroupItem &item, const Path& ) override
308 {
309 auto pItem = &item;
310 if (const auto pMenu =
311 dynamic_cast<MenuItem*>( pItem )) {
312 manager.EndMenu();
313 }
314 else
315 if (const auto pConditionalGroup =
316 dynamic_cast<ConditionalGroupItem*>( pItem )) {
317 const bool flag = flags.back();
318 if (!flag)
319 manager.EndOccultCommands();
320 flags.pop_back();
321 }
322 else
323 if ( pItem->Transparent() ) {
324 }
325 else
326 if ( const auto pGroup = dynamic_cast<MenuSection*>( pItem ) ) {
327 }
328 else
329 wxASSERT( false );
330 }
331
332 void DoVisit( SingleItem &item, const Path& ) override
333 {
334 const auto pCurrentMenu = manager.CurrentMenu();
335 if ( !pCurrentMenu ) {
336 // There may have been a mistake in the placement hint that registered
337 // this single item. It's not within any menu.
338 wxASSERT( false );
339 return;
340 }
341 auto pItem = &item;
342 if (const auto pCommand =
343 dynamic_cast<CommandItem*>( pItem )) {
344 manager.AddItem( project,
345 pCommand->name, pCommand->label_in,
346 pCommand->finder, pCommand->callback,
347 pCommand->flags, pCommand->options
348 );
349 }
350 else
351 if (const auto pCommandList =
352 dynamic_cast<CommandGroupItem*>( pItem ) ) {
353 manager.AddItemList(pCommandList->name,
354 pCommandList->items.data(), pCommandList->items.size(),
355 pCommandList->finder, pCommandList->callback,
356 pCommandList->flags, pCommandList->isEffect);
357 }
358 else
359 if (const auto pSpecial =
360 dynamic_cast<SpecialItem*>( pItem )) {
361 wxASSERT( pCurrentMenu );
362 pSpecial->fn( project, *pCurrentMenu );
363 }
364 else
365 wxASSERT( false );
366 }
367
368 void DoSeparator() override
369 {
370 manager.AddSeparator();
371 }
372
374 std::vector<bool> flags;
375};
376}
377
379{
380 // Once only, cause initial population of preferences for the ordering
381 // of some menu items that used to be given in tables but are now separately
382 // registered in several .cpp files; the sequence of registration depends
383 // on unspecified accidents of static initialization order across
384 // compilation units, so we need something specific here to preserve old
385 // default appearance of menus.
386 // But this needs only to mention some strings -- there is no compilation or
387 // link dependency of this source file on those other implementation files.
390 {
391 {wxT(""), wxT(
392 "File,Edit,Select,View,Transport,Tracks,Generate,Effect,Analyze,Tools,Window,Optional,Help"
393 )},
394 {wxT("/Optional/Extra/Part1"), wxT(
395 "Transport,Tools,Mixer,Edit,PlayAtSpeed,Seek,Device,Select"
396 )},
397 {wxT("/Optional/Extra/Part2"), wxT(
398 "Navigation,Focus,Cursor,Track,Scriptables1,Scriptables2"
399 )},
400 {wxT("/View/Windows"), wxT("UndoHistory,Karaoke,MixerBoard")},
401 {wxT("/Analyze/Analyzers/Windows"), wxT("ContrastAnalyser,PlotSpectrum")},
402 {wxT("/Transport/Basic"), wxT("Play,Record,Scrubbing,Cursor")},
403 {wxT("/View/Other/Toolbars/Toolbars/Other"), wxT(
404"ShowTransportTB,ShowToolsTB,ShowRecordMeterTB,ShowPlayMeterTB,"
405//"ShowMeterTB,"
406"ShowMixerTB,"
407"ShowEditTB,ShowTranscriptionTB,ShowScrubbingTB,ShowDeviceTB,ShowSelectionTB,"
408"ShowSpectralSelectionTB") },
409 {wxT("/Tracks/Add/Add"), wxT(
410 "NewMonoTrack,NewStereoTrack,NewLabelTrack,NewTimeTrack")},
411 }
412 };
413
414 auto &commandManager = CommandManager::Get( project );
415
416 // The list of defaults to exclude depends on
417 // preference wxT("/GUI/Shortcuts/FullDefaults"), which may have changed.
418 commandManager.SetMaxList();
419
420 auto menubar = commandManager.AddMenuBar(wxT("appmenu"));
421 wxASSERT(menubar);
422
423 MenuItemVisitor visitor{ project, commandManager };
424 MenuManager::Visit( visitor );
425
426 GetProjectFrame( project ).SetMenuBar(menubar.release());
427
428 mLastFlags = AlwaysEnabledFlag;
429
430#if defined(_DEBUG)
431// c->CheckDups();
432#endif
433}
434
436{
437 static const auto menuTree = MenuTable::Items( MenuPathStart );
438
439 wxLogNull nolog;
440 Registry::Visit( visitor, menuTree.get(), &sRegistry() );
441}
442
443// TODO: This surely belongs in CommandManager?
445{
447 auto &undoManager = UndoManager::Get( project );
448 auto &commandManager = CommandManager::Get( project );
449 int cur = undoManager.GetCurrentState();
450
451 if (undoManager.UndoAvailable()) {
452 undoManager.GetShortDescription(cur, &desc);
453 commandManager.Modify(wxT("Undo"),
454 XXO("&Undo %s")
455 .Format( desc ));
456 commandManager.Enable(wxT("Undo"),
457 ProjectHistory::Get( project ).UndoAvailable());
458 }
459 else {
460 commandManager.Modify(wxT("Undo"),
461 XXO("&Undo"));
462 }
463
464 if (undoManager.RedoAvailable()) {
465 undoManager.GetShortDescription(cur+1, &desc);
466 commandManager.Modify(wxT("Redo"),
467 XXO("&Redo %s")
468 .Format( desc ));
469 commandManager.Enable(wxT("Redo"),
470 ProjectHistory::Get( project ).RedoAvailable());
471 }
472 else {
473 commandManager.Modify(wxT("Redo"),
474 XXO("&Redo"));
475 commandManager.Enable(wxT("Redo"), false);
476 }
477}
478
479// Get hackcess to a protected method
480class wxFrameEx : public wxFrame
481{
482public:
483 using wxFrame::DetachMenuBar;
484};
485
487{
488 // On OSX, we can't rebuild the menus while a modal dialog is being shown
489 // since the enabled state for menus like Quit and Preference gets out of
490 // sync with wxWidgets idea of what it should be.
491#if defined(__WXMAC__) && defined(_DEBUG)
492 {
493 wxDialog *dlg =
494 wxDynamicCast(wxGetTopLevelParent(wxWindow::FindFocus()), wxDialog);
495 wxASSERT((!dlg || !dlg->IsModal()));
496 }
497#endif
498
499 // Delete the menus, since we will soon recreate them.
500 // Rather oddly, the menus don't vanish as a result of doing this.
501 {
502 auto &window = static_cast<wxFrameEx&>( GetProjectFrame( project ) );
503 wxWindowPtr<wxMenuBar> menuBar{ window.GetMenuBar() };
504 window.DetachMenuBar();
505 // menuBar gets deleted here
506 }
507
508 CommandManager::Get( project ).PurgeData();
509
510 CreateMenusAndCommands(project);
511}
512
514{
515 switch (message.type) {
520 break;
521 default:
522 return;
523 }
524 ModifyUndoMenuItems( mProject );
525 UpdateMenus();
526}
527
528namespace{
529 using Predicates = std::vector< ReservedCommandFlag::Predicate >;
531 {
532 static Predicates thePredicates;
533 return thePredicates;
534 }
535 std::vector< CommandFlagOptions > &Options()
536 {
537 static std::vector< CommandFlagOptions > options;
538 return options;
539 }
540}
541
543 const Predicate &predicate, const CommandFlagOptions &options )
544{
545 static size_t sNextReservedFlag = 0;
546 // This will throw std::out_of_range if the constant NCommandFlags is too
547 // small
548 set( sNextReservedFlag++ );
549 RegisteredPredicates().emplace_back( predicate );
550 Options().emplace_back( options );
551}
552
554{
555 // This method determines all of the flags that determine whether
556 // certain menu items and commands should be enabled or disabled,
557 // and returns them in a bitfield. Note that if none of the flags
558 // have changed, it's not necessary to even check for updates.
559
560 // static variable, used to remember flags for next time.
561 static CommandFlag lastFlags;
562
563 CommandFlag flags, quickFlags;
564
565 const auto &options = Options();
566 size_t ii = 0;
567 for ( const auto &predicate : RegisteredPredicates() ) {
568 if ( options[ii].quickTest ) {
569 quickFlags[ii] = true;
570 if( predicate( mProject ) )
571 flags[ii] = true;
572 }
573 ++ii;
574 }
575
576 if ( checkActive && !GetProjectFrame( mProject ).IsActive() )
577 // quick 'short-circuit' return.
578 flags = (lastFlags & ~quickFlags) | flags;
579 else {
580 ii = 0;
581 for ( const auto &predicate : RegisteredPredicates() ) {
582 if ( !options[ii].quickTest && predicate( mProject ) )
583 flags[ii] = true;
584 ++ii;
585 }
586 }
587
588 lastFlags = flags;
589 return flags;
590}
591
593{
594 for (auto pProject : AllProjects{}) {
595 auto &project = *pProject;
596 MenuManager::Get(project).ModifyToolbarMenus(project);
597 }
598}
599
601{
602 // Refreshes can occur during shutdown and the toolmanager may already
603 // be deleted, so protect against it.
604 auto &toolManager = ToolManager::Get( project );
605
606 auto &settings = ProjectSettings::Get( project );
607
608 // Now, go through each toolbar, and call EnableDisableButtons()
609 for (int i = 0; i < ToolBarCount; i++) {
610 auto bar = toolManager.GetToolBar(i);
611 if (bar)
612 bar->EnableDisableButtons();
613 }
614
615 // These don't really belong here, but it's easier and especially so for
616 // the Edit toolbar and the sync-lock menu item.
617 bool active;
618
619 gPrefs->Read(wxT("/GUI/SyncLockTracks"), &active, false);
620 settings.SetSyncLock(active);
621
622 CommandManager::Get( project ).UpdateCheckmarks( project );
623}
624
625namespace
626{
627 using MenuItemEnablers = std::vector<MenuItemEnabler>;
629 {
630 static MenuItemEnablers enablers;
631 return enablers;
632 }
633}
634
636 const MenuItemEnabler &enabler )
637{
638 Enablers().emplace_back( enabler );
639}
640
641// checkActive is a temporary hack that should be removed as soon as we
642// get multiple effect preview working
643void MenuManager::UpdateMenus( bool checkActive )
644{
645 auto &project = mProject;
646
647 auto flags = GetUpdateFlags(checkActive);
648 // Return from this function if nothing's changed since
649 // the last time we were here.
650 if (flags == mLastFlags)
651 return;
652 mLastFlags = flags;
653
654 auto flags2 = flags;
655
656 // We can enable some extra items if we have select-all-on-none.
657 //EXPLAIN-ME: Why is this here rather than in GetUpdateFlags()?
658 //ANSWER: Because flags2 is used in the menu enable/disable.
659 //The effect still needs flags to determine whether it will need
660 //to actually do the 'select all' to make the command valid.
661
662 for ( const auto &enabler : Enablers() ) {
663 auto actual = enabler.actualFlags();
664 if (
665 enabler.applicable( project ) && (flags & actual) == actual
666 )
667 flags2 |= enabler.possibleFlags();
668 }
669
670 auto &commandManager = CommandManager::Get( project );
671
672 // With select-all-on-none, some items that we don't want enabled may have
673 // been enabled, since we changed the flags. Here we manually disable them.
674 // 0 is grey out, 1 is Autoselect, 2 is Give warnings.
675 commandManager.EnableUsingFlags(
676 flags2, // the "lax" flags
677 (mWhatIfNoSelection == 0 ? flags2 : flags) // the "strict" flags
678 );
679
681}
682
686
688{
689 for( auto p : AllProjects{} ) {
691#if defined(__WXGTK__)
692 // Workaround for:
693 //
694 // http://bugzilla.audacityteam.org/show_bug.cgi?id=458
695 //
696 // This workaround should be removed when Audacity updates to wxWidgets 3.x which has a fix.
697 auto &window = GetProjectFrame( *p );
698 wxRect r = window.GetRect();
699 window.SetSize(wxSize(1,1));
700 window.SetSize(r.GetSize());
701#endif
702 }
703}
704
706 const TranslatableString & Name, CommandFlag & flags, CommandFlag flagsRqd )
707{
708 auto &project = mProject;
709 bool bAllowed = TryToMakeActionAllowed( flags, flagsRqd );
710 if( bAllowed )
711 return true;
712 auto &cm = CommandManager::Get( project );
713 TellUserWhyDisallowed( Name, flags & flagsRqd, flagsRqd);
714 return false;
715}
716
721 CommandFlag & flags, CommandFlag flagsRqd )
722{
723 auto &project = mProject;
724
725 if( flags.none() )
726 flags = GetUpdateFlags();
727
728 // Visit the table of recovery actions
729 auto &enablers = Enablers();
730 auto iter = enablers.begin(), end = enablers.end();
731 while ((flags & flagsRqd) != flagsRqd && iter != end) {
732 const auto &enabler = *iter;
733 auto actual = enabler.actualFlags();
734 auto MissingFlags = (~flags & flagsRqd);
735 if (
736 // Do we have the right precondition?
737 (flags & actual) == actual
738 &&
739 // Can we get the condition we need?
740 (MissingFlags & enabler.possibleFlags()).any()
741 ) {
742 // Then try the function
743 enabler.tryEnable( project, flagsRqd );
744 flags = GetUpdateFlags();
745 }
746 ++iter;
747 }
748 return (flags & flagsRqd) == flagsRqd;
749}
750
752 const TranslatableString & Name, CommandFlag flagsGot, CommandFlag flagsRequired )
753{
754 // The default string for 'reason' is a catch all. I hope it won't ever be seen
755 // and that we will get something more specific.
756 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.");
757 // The default title string is 'Disallowed'.
758 auto untranslatedTitle = XO("Disallowed");
759 wxString helpPage;
760
761 bool enableDefaultMessage = true;
762 bool defaultMessage = true;
763
764 auto doOption = [&](const CommandFlagOptions &options) {
765 if ( options.message ) {
766 reason = options.message( Name );
767 defaultMessage = false;
768 if ( !options.title.empty() )
769 untranslatedTitle = options.title;
770 helpPage = options.helpPage;
771 return true;
772 }
773 else {
774 enableDefaultMessage =
775 enableDefaultMessage && options.enableDefaultMessage;
776 return false;
777 }
778 };
779
780 const auto &alloptions = Options();
781 auto missingFlags = flagsRequired & ~flagsGot;
782
783 // Find greatest priority
784 unsigned priority = 0;
785 for ( const auto &options : alloptions )
786 priority = std::max( priority, options.priority );
787
788 // Visit all unsatisfied conditions' options, by descending priority,
789 // stopping when we find a message
790 ++priority;
791 while( priority-- ) {
792 size_t ii = 0;
793 for ( const auto &options : alloptions ) {
794 if (
795 priority == options.priority
796 &&
797 missingFlags[ii]
798 &&
799 doOption( options ) )
800 goto done;
801
802 ++ii;
803 }
804 }
805 done:
806
807 if (
808 // didn't find a message
809 defaultMessage
810 &&
811 // did find a condition that suppresses the default message
812 !enableDefaultMessage
813 )
814 return;
815
816 // Does not have the warning icon...
818 untranslatedTitle,
819 reason,
820 helpPage);
821}
Toolkit-neutral facade for basic user interface services.
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
std::bitset< NCommandFlags > CommandFlag
Definition: CommandFlag.h:31
void(CommandHandlerObject::*)(const CommandContext &context) CommandFunctorPointer
std::function< CommandHandlerObject &(AudacityProject &) > CommandHandlerFinder
wxEvtHandler CommandHandlerObject
const TranslatableString desc
Definition: ExportPCM.cpp:58
#define set(f, v)
#define XXO(s)
Definition: Internat.h:44
#define XO(s)
Definition: Internat.h:31
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: Menus.cpp:66
static const auto title
FileConfig * gPrefs
Definition: Prefs.cpp:71
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 ...
accessors for certain important windows associated with each project
static const AttachedProjectObjects::RegisteredFactory manager
@ ToolBarCount
Definition: ToolBar.h:88
static Settings & settings()
Definition: TrackInfo.cpp:87
static const auto MenuPathStart
static std::once_flag flag
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:266
CommandManager implements a system for organizing all user-callable commands.
void UpdateCheckmarks(AudacityProject &project)
static CommandManager & Get(AudacityProject &project)
Abstract base class used in importing a file.
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
static void RebuildAllMenuBars()
Definition: Menus.cpp:687
unsigned mRepeatAnalyzerFlags
Definition: Menus.h:68
unsigned mRepeatEffectFlags
Definition: Menus.h:67
unsigned mRepeatGeneratorFlags
Definition: Menus.h:66
int mLastToolRegistration
Definition: Menus.h:58
unsigned mRepeatToolFlags
Definition: Menus.h:69
int mLastAnalyzerRegistration
Definition: Menus.h:55
@ repeattypenone
Definition: Menus.h:61
void RebuildMenuBar(AudacityProject &project)
Definition: Menus.cpp:486
~MenuCreator()
Definition: Menus.cpp:62
void CreateMenusAndCommands(AudacityProject &project)
Definition: Menus.cpp:378
MenuCreator()
Definition: Menus.cpp:51
MenuManager handles updates to menu state.
Definition: Menus.h:78
int mWhatIfNoSelection
Definition: Menus.h:124
static void Visit(ToolbarMenuVisitor &visitor)
Definition: Menus.cpp:435
void OnUndoRedo(struct UndoRedoMessage)
Definition: Menus.cpp:513
bool TryToMakeActionAllowed(CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:720
static void ModifyToolbarMenus(AudacityProject &project)
Definition: Menus.cpp:600
void UpdatePrefs() override
Definition: Menus.cpp:93
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:71
static void ModifyAllProjectToolbarMenus()
Definition: Menus.cpp:592
~MenuManager()
Definition: Menus.cpp:89
MenuManager(AudacityProject &project)
Definition: Menus.cpp:81
bool ReportIfActionNotAllowed(const TranslatableString &Name, CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:705
static void ModifyUndoMenuItems(AudacityProject &project)
Definition: Menus.cpp:444
bool mStopIfWasPaused
Definition: Menus.h:125
void UpdateMenus(bool checkActive=true)
Definition: Menus.cpp:643
CommandFlag GetUpdateFlags(bool checkActive=false) const
Definition: Menus.cpp:553
Observer::Subscription mUndoSubscription
Definition: Menus.h:119
void TellUserWhyDisallowed(const TranslatableString &Name, CommandFlag flagsGot, CommandFlag flagsRequired)
Definition: Menus.cpp:751
static CommandHandlerFinder sFinder
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
std::vector< Identifier > Path
Definition: Registry.h:245
std::function< bool(const AudacityProject &) > Predicate
Definition: CommandFlag.h:91
ReservedCommandFlag(const Predicate &predicate, const CommandFlagOptions &options={})
Definition: Menus.cpp:542
static ToolManager & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:67
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:241
void DestroyRegistry()
Definition: Menus.cpp:267
std::unique_ptr< MenuItems > Items(const Identifier &internalName, Args &&... args)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
Definition: Menus.h:36
void Visit(Visitor &visitor, BaseItem *pTopItem, const GroupItem *pRegistry)
Definition: Registry.cpp:713
std::unique_ptr< BaseItem > BaseItemPtr
Definition: Registry.h:71
std::vector< BaseItemPtr > BaseItemPtrs
Definition: Registry.h:73
void RegisterItem(GroupItem &registry, const Placement &placement, BaseItemPtr pItem)
Definition: Registry.cpp:750
std::vector< MenuItemEnabler > MenuItemEnablers
Definition: Menus.cpp:627
std::vector< ReservedCommandFlag::Predicate > Predicates
Definition: Menus.cpp:529
Predicates & RegisteredPredicates()
Definition: Menus.cpp:530
static Registry::GroupItem & sRegistry()
Definition: Menus.cpp:254
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:535
MenuItemEnablers & Enablers()
Definition: Menus.cpp:628
STL namespace.
AttachedItem(const Placement &placement, BaseItemPtr pItem)
Definition: Menus.cpp:261
~CommandGroupItem() override
Definition: Menus.cpp:226
CommandGroupItem(const Identifier &name_, std::vector< ComponentInterfaceSymbol > items_, CommandFunctorPointer callback_, CommandFlag flags_, bool isEffect_, CommandHandlerFinder finder_)
Definition: Menus.cpp:216
~CommandItem() override
Definition: Menus.cpp:214
CommandItem(const CommandID &name_, const TranslatableString &label_in_, CommandFunctorPointer callback_, CommandFlag flags_, const CommandManager::Options &options_, CommandHandlerFinder finder_)
Definition: Menus.cpp:204
std::function< bool() > Condition
ConditionalGroupItem(const Identifier &internalName, Condition condition_, BaseItemPtrs &&items_)
Definition: Menus.cpp:196
MenuItem(const Identifier &internalName, const TranslatableString &title_, BaseItemPtrs &&items_)
Definition: Menus.cpp:187
~MenuItem() override
Definition: Menus.cpp:194
virtual ~MenuSection()
Definition: Menus.cpp:230
~SpecialItem() override
Definition: Menus.cpp:228
virtual ~WholeMenu()
Definition: Menus.cpp:231
void MaybeDoSeparator()
Definition: Menus.cpp:156
virtual void DoBeginGroup(Registry::GroupItem &item, const Path &path)
Definition: Menus.cpp:169
void Visit(Registry::SingleItem &item, const Path &path) final
Definition: Menus.cpp:150
void BeginGroup(Registry::GroupItem &item, const Path &path) final
Definition: Menus.cpp:108
virtual void DoEndGroup(Registry::GroupItem &item, const Path &path)
Definition: Menus.cpp:173
std::vector< bool > firstItem
virtual void DoSeparator()
Definition: Menus.cpp:181
virtual void DoVisit(Registry::SingleItem &item, const Path &path)
Definition: Menus.cpp:177
void EndGroup(Registry::GroupItem &item, const Path &) final
Definition: Menus.cpp:133
std::vector< bool > needSeparator
RegisteredMenuItemEnabler(const MenuItemEnabler &enabler)
Definition: Menus.cpp:635
BaseItemPtrs items
Definition: Registry.h:141
Type of message published by UndoManager.
Definition: UndoManager.h:61
enum UndoRedoMessage::Type type
void DoVisit(SingleItem &item, const Path &) override
Definition: Menus.cpp:332
void DoBeginGroup(GroupItem &item, const Path &) override
Definition: Menus.cpp:281
MenuItemVisitor(AudacityProject &proj, CommandManager &man)
Definition: Menus.cpp:278
void DoEndGroup(GroupItem &item, const Path &) override
Definition: Menus.cpp:307