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 "ProjectWindows.h"
38#include "UndoManager.h"
41#include "BasicUI.h"
42
43#include <unordered_set>
44
45#include <wx/menu.h>
46#include <wx/windowptr.h>
47#include <wx/log.h>
48
50{
53
58}
59
61{
62}
63
65 []( AudacityProject &project ){
66 return std::make_shared< MenuManager >( project ); }
67};
68
70{
71 return project.AttachedObjects::Get< MenuManager >( key );
72}
73
75{
76 return Get( const_cast< AudacityProject & >( project ) );
77}
78
80 : mProject{ project }
81{
85}
86
88{
89}
90
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}
105
107{
108 bool isMenu = false;
109 bool isExtension = false;
110 auto pItem = &item;
111 if ( pItem->Transparent() ) {
112 }
113 else if ( dynamic_cast<MenuTable::MenuSection*>( pItem ) ) {
114 if ( !needSeparator.empty() )
115 needSeparator.back() = true;
116 }
117 else if ( auto pWhole = dynamic_cast<MenuTable::WholeMenu*>( pItem ) ) {
118 isMenu = true;
119 isExtension = pWhole->extension;
121 }
122
123 DoBeginGroup( item, path );
124
125 if ( isMenu ) {
126 needSeparator.push_back( false );
127 firstItem.push_back( !isExtension );
128 }
129}
130
132{
133 auto pItem = &item;
134 if ( pItem->Transparent() ) {
135 }
136 else if ( dynamic_cast<MenuTable::MenuSection*>( pItem ) ) {
137 if ( !needSeparator.empty() )
138 needSeparator.back() = true;
139 }
140 else if ( dynamic_cast<MenuTable::WholeMenu*>( pItem ) ) {
141 firstItem.pop_back();
142 needSeparator.pop_back();
143 }
144
145 DoEndGroup( item, path );
146}
147
149{
151 DoVisit( item, path );
152}
153
155{
156 bool separate = false;
157 if ( !needSeparator.empty() ) {
158 separate = needSeparator.back() && !firstItem.back();
159 needSeparator.back() = false;
160 firstItem.back() = false;
161 }
162
163 if ( separate )
164 DoSeparator();
165}
166
168{
169}
170
172{
173}
174
176{
177}
178
180{
181}
182
183namespace MenuTable {
184
185MenuItem::MenuItem( const Identifier &internalName,
186 const TranslatableString &title_, BaseItemPtrs &&items_ )
188 internalName, std::move( items_ ) }, title{ title_ }
189{
190 wxASSERT( !title.empty() );
191}
193
195 const Identifier &internalName, Condition condition_, BaseItemPtrs &&items_ )
197 internalName, std::move( items_ ) }, condition{ condition_ }
198{
199}
201
203 const TranslatableString &label_in_,
204 CommandFunctorPointer callback_,
205 CommandFlag flags_,
206 const CommandManager::Options &options_,
207 CommandHandlerFinder finder_)
208: SingleItem{ name_ }, label_in{ label_in_ }
209, finder{ finder_ }, callback{ callback_ }
210, flags{ flags_ }, options{ options_ }
211{}
213
215 std::vector< ComponentInterfaceSymbol > items_,
216 CommandFunctorPointer callback_,
217 CommandFlag flags_,
218 bool isEffect_,
219 CommandHandlerFinder finder_)
220: SingleItem{ name_ }, items{ std::move(items_) }
221, finder{ finder_ }, callback{ callback_ }
222, flags{ flags_ }, isEffect{ isEffect_ }
223{}
225
227
230
232 [](AudacityProject &project) -> CommandHandlerObject & {
233 // If this default finder function is reached, then FinderScope should
234 // have been used somewhere but was not, or an explicit
235 // CommandHandlerFinder was not passed to menu item constructors
236 wxASSERT( false );
237 return project;
238 };
239
240}
241
245
246namespace {
247
248using namespace Registry;
249
250const auto MenuPathStart = wxT("MenuBar");
251
253{
255 return registry;
256}
257}
258
260 const Placement &placement, BaseItemPtr pItem )
261{
262 Registry::RegisterItem( sRegistry(), placement, std::move( pItem ) );
263}
264
266{
267 sRegistry().items.clear();
268}
269
270namespace {
271
272using namespace MenuTable;
273
275{
277 : ToolbarMenuVisitor(proj), manager( man ) {}
278
279 void DoBeginGroup( GroupItem &item, const Path& ) override
280 {
281 auto pItem = &item;
282 if (const auto pMenu =
283 dynamic_cast<MenuItem*>( pItem )) {
284 manager.BeginMenu( pMenu->title );
285 }
286 else
287 if (const auto pConditionalGroup =
288 dynamic_cast<ConditionalGroupItem*>( pItem )) {
289 const auto flag = pConditionalGroup->condition();
290 if (!flag)
291 manager.BeginOccultCommands();
292 // to avoid repeated call of condition predicate in EndGroup():
293 flags.push_back(flag);
294 }
295 else
296 if ( pItem->Transparent() ) {
297 }
298 else
299 if ( const auto pGroup = dynamic_cast<MenuSection*>( pItem ) ) {
300 }
301 else
302 wxASSERT( false );
303 }
304
305 void DoEndGroup( GroupItem &item, const Path& ) override
306 {
307 auto pItem = &item;
308 if (const auto pMenu =
309 dynamic_cast<MenuItem*>( pItem )) {
310 manager.EndMenu();
311 }
312 else
313 if (const auto pConditionalGroup =
314 dynamic_cast<ConditionalGroupItem*>( pItem )) {
315 const bool flag = flags.back();
316 if (!flag)
317 manager.EndOccultCommands();
318 flags.pop_back();
319 }
320 else
321 if ( pItem->Transparent() ) {
322 }
323 else
324 if ( const auto pGroup = dynamic_cast<MenuSection*>( pItem ) ) {
325 }
326 else
327 wxASSERT( false );
328 }
329
330 void DoVisit( SingleItem &item, const Path& ) override
331 {
332 const auto pCurrentMenu = manager.CurrentMenu();
333 if ( !pCurrentMenu ) {
334 // There may have been a mistake in the placement hint that registered
335 // this single item. It's not within any menu.
336 wxASSERT( false );
337 return;
338 }
339 auto pItem = &item;
340 if (const auto pCommand =
341 dynamic_cast<CommandItem*>( pItem )) {
342 manager.AddItem( project,
343 pCommand->name, pCommand->label_in,
344 pCommand->finder, pCommand->callback,
345 pCommand->flags, pCommand->options
346 );
347 }
348 else
349 if (const auto pCommandList =
350 dynamic_cast<CommandGroupItem*>( pItem ) ) {
351 manager.AddItemList(pCommandList->name,
352 pCommandList->items.data(), pCommandList->items.size(),
353 pCommandList->finder, pCommandList->callback,
354 pCommandList->flags, pCommandList->isEffect);
355 }
356 else
357 if (const auto pSpecial =
358 dynamic_cast<SpecialItem*>( pItem )) {
359 wxASSERT( pCurrentMenu );
360 pSpecial->fn( project, *pCurrentMenu );
361 }
362 else
363 wxASSERT( false );
364 }
365
366 void DoSeparator() override
367 {
368 manager.AddSeparator();
369 }
370
372 std::vector<bool> flags;
373};
374}
375
377{
378 // Once only, cause initial population of preferences for the ordering
379 // of some menu items that used to be given in tables but are now separately
380 // registered in several .cpp files; the sequence of registration depends
381 // on unspecified accidents of static initialization order across
382 // compilation units, so we need something specific here to preserve old
383 // default appearance of menus.
384 // But this needs only to mention some strings -- there is no compilation or
385 // link dependency of this source file on those other implementation files.
388 {
389 {wxT(""), wxT(
390"File,Edit,Select,View,Transport,Tracks,Generate,Effect,Analyze,Tools,Window,Optional,Help"
391 )},
392 {wxT("/Optional/Extra/Part1"), wxT(
393"Transport,Tools,Mixer,Edit,PlayAtSpeed,Seek,Device,Select"
394 )},
395 {wxT("/Optional/Extra/Part2"), wxT(
396"Navigation,Focus,Cursor,Track,Scriptables1,Scriptables2"
397 )},
398 {wxT("/View/Windows"), wxT("UndoHistory,Karaoke,MixerBoard")},
399 {wxT("/Analyze/Analyzers/Windows"), wxT("ContrastAnalyser,PlotSpectrum")},
400 {wxT("/Transport/Basic"), wxT("Play,Record,Scrubbing,Cursor")},
401 {wxT("/View/Other/Toolbars/Toolbars/Other"), wxT(
402"ShowTransportTB,ShowToolsTB,ShowRecordMeterTB,ShowPlayMeterTB,"
403//"ShowMeterTB,"
404"ShowMixerTB,"
405"ShowEditTB,ShowTranscriptionTB,ShowScrubbingTB,ShowDeviceTB,ShowSelectionTB,"
406"ShowSpectralSelectionTB") },
407 {wxT("/Tracks/Add/Add"), wxT(
408"NewMonoTrack,NewStereoTrack,NewLabelTrack,NewTimeTrack")},
409 {wxT("/Optional/Extra/Part2/Scriptables1"), wxT(
410"SelectTime,SelectFrequencies,SelectTracks,SetTrackStatus,SetTrackAudio,"
411"SetTrackVisuals,GetPreference,SetPreference,SetClip,SetEnvelope,SetLabel"
412"SetProject") },
413 {wxT("/Optional/Extra/Part2/Scriptables2"), wxT(
414"Select,SetTrack,GetInfo,Message,Help,Import2,Export2,OpenProject2,"
415"SaveProject2,Drag,CompareAudio,Screenshot") },
416 }
417 };
418
419 auto &commandManager = CommandManager::Get( project );
420
421 // The list of defaults to exclude depends on
422 // preference wxT("/GUI/Shortcuts/FullDefaults"), which may have changed.
423 commandManager.SetMaxList();
424
425 auto menubar = commandManager.AddMenuBar(wxT("appmenu"));
426 wxASSERT(menubar);
427
428 MenuItemVisitor visitor{ project, commandManager };
429 MenuManager::Visit( visitor );
430
431 GetProjectFrame( project ).SetMenuBar(menubar.release());
432
433 mLastFlags = AlwaysEnabledFlag;
434
435#if defined(_DEBUG)
436// c->CheckDups();
437#endif
438}
439
441{
442 static const auto menuTree = MenuTable::Items( MenuPathStart );
443
444 wxLogNull nolog;
445 Registry::Visit( visitor, menuTree.get(), &sRegistry() );
446}
447
448// TODO: This surely belongs in CommandManager?
450{
452 auto &undoManager = UndoManager::Get( project );
453 auto &commandManager = CommandManager::Get( project );
454 int cur = undoManager.GetCurrentState();
455
456 if (undoManager.UndoAvailable()) {
457 undoManager.GetShortDescription(cur, &desc);
458 commandManager.Modify(wxT("Undo"),
459 XXO("&Undo %s")
460 .Format( desc ));
461 commandManager.Enable(wxT("Undo"),
462 ProjectHistory::Get( project ).UndoAvailable());
463 }
464 else {
465 commandManager.Modify(wxT("Undo"),
466 XXO("&Undo"));
467 }
468
469 if (undoManager.RedoAvailable()) {
470 undoManager.GetShortDescription(cur+1, &desc);
471 commandManager.Modify(wxT("Redo"),
472 XXO("&Redo %s")
473 .Format( desc ));
474 commandManager.Enable(wxT("Redo"),
475 ProjectHistory::Get( project ).RedoAvailable());
476 }
477 else {
478 commandManager.Modify(wxT("Redo"),
479 XXO("&Redo"));
480 commandManager.Enable(wxT("Redo"), false);
481 }
482}
483
484// Get hackcess to a protected method
485class wxFrameEx : public wxFrame
486{
487public:
488 using wxFrame::DetachMenuBar;
489};
490
492{
493 // On OSX, we can't rebuild the menus while a modal dialog is being shown
494 // since the enabled state for menus like Quit and Preference gets out of
495 // sync with wxWidgets idea of what it should be.
496#if defined(__WXMAC__) && defined(_DEBUG)
497 {
498 wxDialog *dlg =
499 wxDynamicCast(wxGetTopLevelParent(wxWindow::FindFocus()), wxDialog);
500 wxASSERT((!dlg || !dlg->IsModal()));
501 }
502#endif
503
504 // Delete the menus, since we will soon recreate them.
505 // Rather oddly, the menus don't vanish as a result of doing this.
506 {
507 auto &window = static_cast<wxFrameEx&>( GetProjectFrame( project ) );
508 wxWindowPtr<wxMenuBar> menuBar{ window.GetMenuBar() };
509 window.DetachMenuBar();
510 // menuBar gets deleted here
511 }
512
513 CommandManager::Get( project ).PurgeData();
514
515 CreateMenusAndCommands(project);
516}
517
519{
520 switch (message.type) {
525 break;
526 default:
527 return;
528 }
529 ModifyUndoMenuItems( mProject );
530 UpdateMenus();
531}
532
534{
535 // This method determines all of the flags that determine whether
536 // certain menu items and commands should be enabled or disabled,
537 // and returns them in a bitfield. Note that if none of the flags
538 // have changed, it's not necessary to even check for updates.
539
540 // static variable, used to remember flags for next time.
541 static CommandFlag lastFlags;
542
543 CommandFlag flags, quickFlags;
544
545 const auto &options = ReservedCommandFlag::Options();
546 size_t ii = 0;
547 for ( const auto &predicate : ReservedCommandFlag::RegisteredPredicates() ) {
548 if ( options[ii].quickTest ) {
549 quickFlags[ii] = true;
550 if( predicate( mProject ) )
551 flags[ii] = true;
552 }
553 ++ii;
554 }
555
556 if ( checkActive && !GetProjectFrame( mProject ).IsActive() )
557 // quick 'short-circuit' return.
558 flags = (lastFlags & ~quickFlags) | flags;
559 else {
560 ii = 0;
561 for ( const auto &predicate
563 if ( !options[ii].quickTest && predicate( mProject ) )
564 flags[ii] = true;
565 ++ii;
566 }
567 }
568
569 lastFlags = flags;
570 return flags;
571}
572
573// checkActive is a temporary hack that should be removed as soon as we
574// get multiple effect preview working
575void MenuManager::UpdateMenus( bool checkActive )
576{
577 auto &project = mProject;
578
579 auto flags = GetUpdateFlags(checkActive);
580 // Return from this function if nothing's changed since
581 // the last time we were here.
582 if (flags == mLastFlags)
583 return;
584 mLastFlags = flags;
585
586 auto flags2 = flags;
587
588 // We can enable some extra items if we have select-all-on-none.
589 //EXPLAIN-ME: Why is this here rather than in GetUpdateFlags()?
590 //ANSWER: Because flags2 is used in the menu enable/disable.
591 //The effect still needs flags to determine whether it will need
592 //to actually do the 'select all' to make the command valid.
593
594 for ( const auto &enabler : RegisteredMenuItemEnabler::Enablers() ) {
595 auto actual = enabler.actualFlags();
596 if (
597 enabler.applicable( project ) && (flags & actual) == actual
598 )
599 flags2 |= enabler.possibleFlags();
600 }
601
602 auto &commandManager = CommandManager::Get( project );
603
604 // With select-all-on-none, some items that we don't want enabled may have
605 // been enabled, since we changed the flags. Here we manually disable them.
606 // 0 is grey out, 1 is Autoselect, 2 is Give warnings.
607 commandManager.EnableUsingFlags(
608 flags2, // the "lax" flags
609 (mWhatIfNoSelection == 0 ? flags2 : flags) // the "strict" flags
610 );
611
612 Publish({});
613}
614
618
620{
621 for( auto p : AllProjects{} ) {
623#if defined(__WXGTK__)
624 // Workaround for:
625 //
626 // http://bugzilla.audacityteam.org/show_bug.cgi?id=458
627 //
628 // This workaround should be removed when Audacity updates to wxWidgets 3.x which has a fix.
629 auto &window = GetProjectFrame( *p );
630 wxRect r = window.GetRect();
631 window.SetSize(wxSize(1,1));
632 window.SetSize(r.GetSize());
633#endif
634 }
635}
636
638 const TranslatableString & Name, CommandFlag & flags, CommandFlag flagsRqd )
639{
640 auto &project = mProject;
641 bool bAllowed = TryToMakeActionAllowed( flags, flagsRqd );
642 if( bAllowed )
643 return true;
644 auto &cm = CommandManager::Get( project );
645 TellUserWhyDisallowed( Name, flags & flagsRqd, flagsRqd);
646 return false;
647}
648
653 CommandFlag & flags, CommandFlag flagsRqd )
654{
655 auto &project = mProject;
656
657 if( flags.none() )
658 flags = GetUpdateFlags();
659
660 // Visit the table of recovery actions
661 auto &enablers = RegisteredMenuItemEnabler::Enablers();
662 auto iter = enablers.begin(), end = enablers.end();
663 while ((flags & flagsRqd) != flagsRqd && iter != end) {
664 const auto &enabler = *iter;
665 auto actual = enabler.actualFlags();
666 auto MissingFlags = (~flags & flagsRqd);
667 if (
668 // Do we have the right precondition?
669 (flags & actual) == actual
670 &&
671 // Can we get the condition we need?
672 (MissingFlags & enabler.possibleFlags()).any()
673 ) {
674 // Then try the function
675 enabler.tryEnable( project, flagsRqd );
676 flags = GetUpdateFlags();
677 }
678 ++iter;
679 }
680 return (flags & flagsRqd) == flagsRqd;
681}
682
684 const TranslatableString & Name, CommandFlag flagsGot, CommandFlag flagsRequired )
685{
686 // The default string for 'reason' is a catch all. I hope it won't ever be seen
687 // and that we will get something more specific.
688 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.");
689 // The default title string is 'Disallowed'.
690 auto untranslatedTitle = XO("Disallowed");
691 wxString helpPage;
692
693 bool enableDefaultMessage = true;
694 bool defaultMessage = true;
695
696 auto doOption = [&](const CommandFlagOptions &options) {
697 if ( options.message ) {
698 reason = options.message( Name );
699 defaultMessage = false;
700 if ( !options.title.empty() )
701 untranslatedTitle = options.title;
702 helpPage = options.helpPage;
703 return true;
704 }
705 else {
706 enableDefaultMessage =
707 enableDefaultMessage && options.enableDefaultMessage;
708 return false;
709 }
710 };
711
712 const auto &alloptions = ReservedCommandFlag::Options();
713 auto missingFlags = flagsRequired & ~flagsGot;
714
715 // Find greatest priority
716 unsigned priority = 0;
717 for ( const auto &options : alloptions )
718 priority = std::max( priority, options.priority );
719
720 // Visit all unsatisfied conditions' options, by descending priority,
721 // stopping when we find a message
722 ++priority;
723 while( priority-- ) {
724 size_t ii = 0;
725 for ( const auto &options : alloptions ) {
726 if (
727 priority == options.priority
728 &&
729 missingFlags[ii]
730 &&
731 doOption( options ) )
732 goto done;
733
734 ++ii;
735 }
736 }
737 done:
738
739 if (
740 // didn't find a message
741 defaultMessage
742 &&
743 // did find a condition that suppresses the default message
744 !enableDefaultMessage
745 )
746 return;
747
748 // Does not have the warning icon...
750 untranslatedTitle,
751 reason,
752 helpPage);
753}
wxT("CloseDown"))
Toolkit-neutral facade for basic user interface services.
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:34
std::bitset< NCommandFlags > CommandFlag
Definition: CommandFlag.h:30
std::function< CommandHandlerObject &(AudacityProject &) > CommandHandlerFinder
wxEvtHandler CommandHandlerObject
const TranslatableString desc
Definition: ExportPCM.cpp:55
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: Menus.cpp:64
static const auto title
FileConfig * gPrefs
Definition: Prefs.cpp:70
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
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:90
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.
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:619
unsigned mRepeatAnalyzerFlags
Definition: Menus.h:67
@ repeattypenone
Definition: Menus.h:60
unsigned mRepeatEffectFlags
Definition: Menus.h:66
unsigned mRepeatGeneratorFlags
Definition: Menus.h:65
int mLastToolRegistration
Definition: Menus.h:57
unsigned mRepeatToolFlags
Definition: Menus.h:68
int mLastAnalyzerRegistration
Definition: Menus.h:54
void RebuildMenuBar(AudacityProject &project)
Definition: Menus.cpp:491
~MenuCreator()
Definition: Menus.cpp:60
void CreateMenusAndCommands(AudacityProject &project)
Definition: Menus.cpp:376
MenuCreator()
Definition: Menus.cpp:49
MenuManager handles updates to menu state.
Definition: Menus.h:81
int mWhatIfNoSelection
Definition: Menus.h:124
static void Visit(ToolbarMenuVisitor &visitor)
Definition: Menus.cpp:440
void OnUndoRedo(struct UndoRedoMessage)
Definition: Menus.cpp:518
bool TryToMakeActionAllowed(CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:652
void UpdatePrefs() override
Definition: Menus.cpp:91
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:69
~MenuManager()
Definition: Menus.cpp:87
MenuManager(AudacityProject &project)
Definition: Menus.cpp:79
bool ReportIfActionNotAllowed(const TranslatableString &Name, CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:637
static void ModifyUndoMenuItems(AudacityProject &project)
Definition: Menus.cpp:449
bool mStopIfWasPaused
Definition: Menus.h:125
void UpdateMenus(bool checkActive=true)
Definition: Menus.cpp:575
CommandFlag GetUpdateFlags(bool checkActive=false) const
Definition: Menus.cpp:533
Observer::Subscription mUndoSubscription
Definition: Menus.h:119
void TellUserWhyDisallowed(const TranslatableString &Name, CommandFlag flagsGot, CommandFlag flagsRequired)
Definition: Menus.cpp:683
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)
std::vector< Identifier > Path
Definition: Registry.h:245
static const Predicates & RegisteredPredicates()
Definition: CommandFlag.cpp:27
static const std::vector< CommandFlagOptions > & Options()
Definition: CommandFlag.cpp:32
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:254
void DestroyRegistry()
Definition: Menus.cpp:265
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:35
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
static Registry::GroupItem & sRegistry()
Definition: Menus.cpp:252
STL namespace.
AttachedItem(const Placement &placement, BaseItemPtr pItem)
Definition: Menus.cpp:259
~CommandGroupItem() override
Definition: Menus.cpp:224
CommandGroupItem(const Identifier &name_, std::vector< ComponentInterfaceSymbol > items_, CommandFunctorPointer callback_, CommandFlag flags_, bool isEffect_, CommandHandlerFinder finder_)
Definition: Menus.cpp:214
~CommandItem() override
Definition: Menus.cpp:212
CommandItem(const CommandID &name_, const TranslatableString &label_in_, CommandFunctorPointer callback_, CommandFlag flags_, const CommandManager::Options &options_, CommandHandlerFinder finder_)
Definition: Menus.cpp:202
std::function< bool() > Condition
ConditionalGroupItem(const Identifier &internalName, Condition condition_, BaseItemPtrs &&items_)
Definition: Menus.cpp:194
MenuItem(const Identifier &internalName, const TranslatableString &title_, BaseItemPtrs &&items_)
Definition: Menus.cpp:185
~MenuItem() override
Definition: Menus.cpp:192
virtual ~MenuSection()
Definition: Menus.cpp:228
~SpecialItem() override
Definition: Menus.cpp:226
virtual ~WholeMenu()
Definition: Menus.cpp:229
void MaybeDoSeparator()
Definition: Menus.cpp:154
virtual void DoBeginGroup(Registry::GroupItem &item, const Path &path)
Definition: Menus.cpp:167
void Visit(Registry::SingleItem &item, const Path &path) final
Definition: Menus.cpp:148
void BeginGroup(Registry::GroupItem &item, const Path &path) final
Definition: Menus.cpp:106
virtual void DoEndGroup(Registry::GroupItem &item, const Path &path)
Definition: Menus.cpp:171
std::vector< bool > firstItem
virtual void DoSeparator()
Definition: Menus.cpp:179
virtual void DoVisit(Registry::SingleItem &item, const Path &path)
Definition: Menus.cpp:175
void EndGroup(Registry::GroupItem &item, const Path &) final
Definition: Menus.cpp:131
std::vector< bool > needSeparator
static const MenuItemEnablers & Enablers()
Definition: CommandFlag.cpp:56
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:330
void DoBeginGroup(GroupItem &item, const Path &) override
Definition: Menus.cpp:279
MenuItemVisitor(AudacityProject &proj, CommandManager &man)
Definition: Menus.cpp:276
void DoEndGroup(GroupItem &item, const Path &) override
Definition: Menus.cpp:305