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