43#include <unordered_set>
46#include <wx/windowptr.h>
66 return std::make_shared< MenuManager >( project ); }
93 bool bSelectAllIfNone;
94 gPrefs->Read(
wxT(
"/GUI/SelectAllOnNone"), &bSelectAllIfNone,
false);
109 bool isExtension =
false;
111 if ( pItem->Transparent() ) {
119 isExtension = pWhole->extension;
134 if ( pItem->Transparent() ) {
156 bool separate =
false;
188 internalName, std::move( items_ ) },
title{ title_ }
190 wxASSERT( !
title.empty() );
197 internalName, std::move( items_ ) }, condition{ condition_ }
209, finder{ finder_ }, callback{ callback_ }
210, flags{ flags_ }, options{ options_ }
215 std::vector< ComponentInterfaceSymbol > items_,
221, finder{ finder_ }, callback{ callback_ }
222, flags{ flags_ }, isEffect{ isEffect_ }
282 if (
const auto pMenu =
284 manager.BeginMenu( pMenu->title );
287 if (
const auto pConditionalGroup =
289 const auto flag = pConditionalGroup->condition();
293 flags.push_back(
flag);
296 if ( pItem->Transparent() ) {
299 if (
const auto pGroup =
dynamic_cast<MenuSection*
>( pItem ) ) {
308 if (
const auto pMenu =
313 if (
const auto pConditionalGroup =
315 const bool flag = flags.back();
321 if ( pItem->Transparent() ) {
324 if (
const auto pGroup =
dynamic_cast<MenuSection*
>( pItem ) ) {
332 const auto pCurrentMenu =
manager.CurrentMenu();
333 if ( !pCurrentMenu ) {
340 if (
const auto pCommand =
343 pCommand->name, pCommand->label_in,
344 pCommand->finder, pCommand->callback,
345 pCommand->flags, pCommand->options
349 if (
const auto pCommandList =
351 manager.AddItemList(pCommandList->name,
352 pCommandList->items.data(), pCommandList->items.size(),
353 pCommandList->finder, pCommandList->callback,
354 pCommandList->flags, pCommandList->isEffect);
357 if (
const auto pSpecial =
359 wxASSERT( pCurrentMenu );
360 pSpecial->fn( project, *pCurrentMenu );
390"File,Edit,Select,View,Transport,Tracks,Generate,Effect,Analyze,Tools,Window,Optional,Help"
392 {
wxT(
"/Optional/Extra/Part1"),
wxT(
393"Transport,Tools,Mixer,Edit,PlayAtSpeed,Seek,Device,Select"
395 {
wxT(
"/Optional/Extra/Part2"),
wxT(
396"Navigation,Focus,Cursor,Track,Scriptables1,Scriptables2"
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,"
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"
413 {
wxT(
"/Optional/Extra/Part2/Scriptables2"),
wxT(
414"Select,SetTrack,GetInfo,Message,Help,Import2,Export2,OpenProject2,"
415"SaveProject2,Drag,CompareAudio,Screenshot") },
423 commandManager.SetMaxList();
425 auto menubar = commandManager.AddMenuBar(
wxT(
"appmenu"));
428 MenuItemVisitor visitor{ project, commandManager };
454 int cur = undoManager.GetCurrentState();
456 if (undoManager.UndoAvailable()) {
457 undoManager.GetShortDescription(cur, &
desc);
458 commandManager.Modify(
wxT(
"Undo"),
461 commandManager.Enable(
wxT(
"Undo"),
465 commandManager.Modify(
wxT(
"Undo"),
469 if (undoManager.RedoAvailable()) {
470 undoManager.GetShortDescription(cur+1, &
desc);
471 commandManager.Modify(
wxT(
"Redo"),
474 commandManager.Enable(
wxT(
"Redo"),
478 commandManager.Modify(
wxT(
"Redo"),
480 commandManager.Enable(
wxT(
"Redo"),
false);
488 using wxFrame::DetachMenuBar;
496#if defined(__WXMAC__) && defined(_DEBUG)
499 wxDynamicCast(wxGetTopLevelParent(wxWindow::FindFocus()), wxDialog);
500 wxASSERT((!dlg || !dlg->IsModal()));
508 wxWindowPtr<wxMenuBar> menuBar{ window.GetMenuBar() };
509 window.DetachMenuBar();
515 CreateMenusAndCommands(project);
520 switch (message.
type) {
529 ModifyUndoMenuItems( mProject );
548 if ( options[ii].quickTest ) {
549 quickFlags[ii] =
true;
550 if( predicate( mProject ) )
558 flags = (lastFlags & ~quickFlags) | flags;
561 for (
const auto &predicate
563 if ( !options[ii].quickTest && predicate( mProject ) )
577 auto &project = mProject;
579 auto flags = GetUpdateFlags(checkActive);
582 if (flags == mLastFlags)
595 auto actual = enabler.actualFlags();
597 enabler.applicable( project ) && (flags & actual) == actual
599 flags2 |= enabler.possibleFlags();
607 commandManager.EnableUsingFlags(
609 (mWhatIfNoSelection == 0 ? flags2 : flags)
623#if defined(__WXGTK__)
630 wxRect r = window.GetRect();
631 window.SetSize(wxSize(1,1));
632 window.SetSize(r.GetSize());
640 auto &project = mProject;
641 bool bAllowed = TryToMakeActionAllowed( flags, flagsRqd );
645 TellUserWhyDisallowed( Name, flags & flagsRqd, flagsRqd);
655 auto &project = mProject;
658 flags = GetUpdateFlags();
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);
669 (flags & actual) == actual
672 (MissingFlags & enabler.possibleFlags()).any()
675 enabler.tryEnable( project, flagsRqd );
676 flags = GetUpdateFlags();
680 return (flags & flagsRqd) == flagsRqd;
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.");
690 auto untranslatedTitle =
XO(
"Disallowed");
693 bool enableDefaultMessage =
true;
694 bool defaultMessage =
true;
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;
706 enableDefaultMessage =
707 enableDefaultMessage && options.enableDefaultMessage;
713 auto missingFlags = flagsRequired & ~flagsGot;
716 unsigned priority = 0;
717 for (
const auto &options : alloptions )
718 priority = std::max( priority, options.priority );
723 while( priority-- ) {
725 for (
const auto &options : alloptions ) {
727 priority == options.priority
731 doOption( options ) )
744 !enableDefaultMessage
Toolkit-neutral facade for basic user interface services.
constexpr CommandFlag AlwaysEnabledFlag
std::bitset< NCommandFlags > CommandFlag
std::function< CommandHandlerObject &(AudacityProject &) > CommandHandlerFinder
wxEvtHandler CommandHandlerObject
const TranslatableString desc
XXO("&Cut/Copy/Paste Toolbar")
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
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
CommandManager implements a system for organizing all user-callable commands.
static CommandManager & Get(AudacityProject &project)
An explicitly nonlocalized string, not meant for the user to see.
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
static ProjectHistory & Get(AudacityProject &project)
std::vector< Identifier > Path
static const Predicates & RegisteredPredicates()
static const std::vector< CommandFlagOptions > & Options()
Holds a msgid for the translation catalog; may also bind format arguments.
static UndoManager & Get(AudacityProject &project)
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.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
void Visit(Visitor &visitor, BaseItem *pTopItem, const GroupItem *pRegistry)
std::unique_ptr< BaseItem > BaseItemPtr
std::vector< BaseItemPtr > BaseItemPtrs
void RegisterItem(GroupItem ®istry, const Placement &placement, BaseItemPtr pItem)
~CommandGroupItem() override
CommandGroupItem(const Identifier &name_, std::vector< ComponentInterfaceSymbol > items_, CommandFunctorPointer callback_, CommandFlag flags_, bool isEffect_, CommandHandlerFinder finder_)
CommandItem(const CommandID &name_, const TranslatableString &label_in_, CommandFunctorPointer callback_, CommandFlag flags_, const CommandManager::Options &options_, CommandHandlerFinder finder_)
Type of message published by UndoManager.
enum UndoRedoMessage::Type type