diff --git a/lib-src/mod-null/ModNullCallback.cpp b/lib-src/mod-null/ModNullCallback.cpp index d201c3419..4ded39a1f 100644 --- a/lib-src/mod-null/ModNullCallback.cpp +++ b/lib-src/mod-null/ModNullCallback.cpp @@ -32,6 +32,7 @@ click from the menu into the actaul function to be called. #include "ShuttleGui.h" #include "Project.h" #include "commands/CommandManager.h" +#include "CommonCommandFlags.h" #if defined(__WXMSW__) #include diff --git a/lib-src/mod-nyq-bench/NyqBench.cpp b/lib-src/mod-nyq-bench/NyqBench.cpp index 26c7ebb70..a2d69d004 100755 --- a/lib-src/mod-nyq-bench/NyqBench.cpp +++ b/lib-src/mod-nyq-bench/NyqBench.cpp @@ -24,6 +24,7 @@ #include #include "AudioIOBase.h" +#include "CommonCommandFlags.h" #include "LabelTrack.h" #include "Menus.h" #include "ModuleManager.h" diff --git a/src/CommonCommandFlags.cpp b/src/CommonCommandFlags.cpp index e69de29bb..800e29500 100644 --- a/src/CommonCommandFlags.cpp +++ b/src/CommonCommandFlags.cpp @@ -0,0 +1,356 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +CommonCommandFlags.cpp + +Paul Licameli split from Menus.cpp + +**********************************************************************/ + +#include "Audacity.h" +#include "CommonCommandFlags.h" + +#include "Experimental.h" + +#include + +#include "AudioIO.h" +#include "LabelTrack.h" +#include "Menus.h" +#include "NoteTrack.h" +#include "Project.h" +#include "ProjectAudioIO.h" +#include "ProjectFileIO.h" +#include "ProjectHistory.h" +#include "ProjectSettings.h" +#include "UndoManager.h" +#include "ViewInfo.h" +#include "WaveTrack.h" +#include "commands/CommandManagerWindowClasses.h" +#include "toolbars/ControlToolBar.h" + +/* + +This file registers functions implementing many of the tests for enabling of +menu items. Sequence of a few of them has minor significance, but for most +there is little reason to keep them in one file. Flags used only by one +other file might instead be defined only where used. + +They are collected here because Menus.cpp is too low level to have the +dependencies implied by the include directives above -- it would make dependency +cycles. + +*/ + +// Really means, some track is selected, that isn't a time track +bool TracksSelectedPred( const AudacityProject &project ) +{ + auto range = TrackList::Get( project ).Selected() + - []( const Track *pTrack ){ + return track_cast( pTrack ); }; + return !range.empty(); +}; + +bool AudioIOBusyPred( const AudacityProject &project ) +{ + return AudioIOBase::Get()->IsAudioTokenActive( + ProjectAudioIO::Get( project ).GetAudioIOToken()); +}; + +bool TimeSelectedPred( const AudacityProject &project ) +{ + // This is equivalent to check if there is a valid selection, + // so it's used for Zoom to Selection too + return !ViewInfo::Get( project ).selectedRegion.isPoint(); +}; + +const CommandFlagOptions cutCopyOptions{ +// In reporting the issue with cut or copy, we don't tell the user they could also select some text in a label. + []( const wxString &Name ) { + // PRL: These strings have hard-coded mention of a certain shortcut key, + // thus assuming the default shortcuts. That is questionable. + wxString format; +#ifdef EXPERIMENTAL_DA + // i18n-hint: %s will be replaced by the name of an action, such as Normalize, Cut, Fade. + format = _("You must first select some audio for '%s' to act on.\n\nCtrl + A selects all audio."); +#else +#ifdef __WXMAC__ + // i18n-hint: %s will be replaced by the name of an action, such as Normalize, Cut, Fade. + format = _("Select the audio for %s to use (for example, Cmd + A to Select All) then try again." + // No need to explain what a help button is for. + // "\n\nClick the Help button to learn more about selection methods." + ); + +#else + // i18n-hint: %s will be replaced by the name of an action, such as Normalize, Cut, Fade. + format = _("Select the audio for %s to use (for example, Ctrl + A to Select All) then try again." + // No need to explain what a help button is for. + // "\n\nClick the Help button to learn more about selection methods." + ); +#endif + return wxString::Format( format, Name ); +#endif + }, + "Selecting_Audio_-_the_basics", + XO("No Audio Selected") +}; + +const ReservedCommandFlag + // The sequence of these definitions has a minor significance in determining + // which user error message has precedence if more than one might apply, so + // they should be kept in this sequence in one .cpp file if it is important + // to preserve that behavior. If they are dispersed to more than one file, + // then the precedence will be unspecified. + // The ordering of the flags that only disable the default message is not + // significant. + AudioIONotBusyFlag{ + [](const AudacityProject &project ){ + return !AudioIOBusyPred( project ); + }, + CommandFlagOptions{ []( const wxString& ) { return + // This reason will not be shown, because options that require it will be greyed out. + _("You can only do this when playing and recording are\nstopped. (Pausing is not sufficient.)"); + } } + .QuickTest() + .Priority( 1 ) + }, //lll + StereoRequiredFlag{ + [](const AudacityProject &project){ + // True iff at least one stereo track is selected, i.e., at least + // one right channel is selected. + // TODO: more-than-two-channels + auto range = TrackList::Get( project ).Selected() + - &Track::IsLeader; + return !range.empty(); + }, + { []( const wxString& ) { return + // This reason will not be shown, because the stereo-to-mono is greyed out if not allowed. + _("You must first select some stereo audio to perform this\naction. (You cannot use this with mono.)"); + } } + }, //lda + TimeSelectedFlag{ + TimeSelectedPred, + cutCopyOptions + }, + WaveTracksSelectedFlag{ + [](const AudacityProject &project){ + return !TrackList::Get( project ).Selected().empty(); + }, + { []( const wxString& ) { return + _("You must first select some audio to perform this action.\n(Selecting other kinds of track won't work.)"); + } } + }, + TracksExistFlag{ + [](const AudacityProject &project){ + return !TrackList::Get( project ).Any().empty(); + }, + CommandFlagOptions{}.DisableDefaultMessage() + }, + TracksSelectedFlag{ + TracksSelectedPred, + { []( const wxString &Name ){ return wxString::Format( + // i18n-hint: %s will be replaced by the name of an action, such as "Remove Tracks". + _("\"%s\" requires one or more tracks to be selected."), + Name + ); } } + }, + TrackPanelHasFocus{ + [](const AudacityProject &project){ + for (auto w = wxWindow::FindFocus(); w; w = w->GetParent()) { + if (dynamic_cast(w)) + return true; + } + return false; + }, + CommandFlagOptions{}.DisableDefaultMessage() + }; //lll + +const ReservedCommandFlag + AudioIOBusyFlag{ + AudioIOBusyPred, + CommandFlagOptions{}.QuickTest() + }, //lll + CaptureNotBusyFlag{ + [](const AudacityProject &){ + auto gAudioIO = AudioIO::Get(); + return !( + gAudioIO->IsBusy() && + gAudioIO->GetNumCaptureChannels() > 0 + ); + } + }, + HasWaveDataFlag{ + [](const AudacityProject &project){ + auto range = TrackList::Get( project ).Any() + + [](const WaveTrack *pTrack){ + return pTrack->GetEndTime() > pTrack->GetStartTime(); + }; + return !range.empty(); + } + }; // jkc + +const ReservedCommandFlag + LabelTracksExistFlag{ + [](const AudacityProject &project){ + return !TrackList::Get( project ).Any().empty(); + } + }, + UnsavedChangesFlag{ + [](const AudacityProject &project){ + auto &undoManager = UndoManager::Get( project ); + return + undoManager.UnsavedChanges() + || + !ProjectFileIO::Get( project ).IsProjectSaved() + ; + } + }, + HasLastEffectFlag{ + [](const AudacityProject &project){ + return !MenuManager::Get( project ).mLastEffect.empty(); + } + }, + UndoAvailableFlag{ + [](const AudacityProject &project){ + return ProjectHistory::Get( project ).UndoAvailable(); + } + }, + RedoAvailableFlag{ + [](const AudacityProject &project){ + return ProjectHistory::Get( project ).RedoAvailable(); + } + }, + ZoomInAvailableFlag{ + [](const AudacityProject &project){ + return + ViewInfo::Get( project ).ZoomInAvailable() + && + !TrackList::Get( project ).Any().empty() + ; + } + }, + ZoomOutAvailableFlag{ + [](const AudacityProject &project){ + return + ViewInfo::Get( project ).ZoomOutAvailable() + && + !TrackList::Get( project ).Any().empty() + ; + } + }, + LabelsSelectedFlag{ + [](const AudacityProject &project){ + // At least one label track selected, having at least one label + // completely within the time selection. + const auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + const auto &test = [&]( const LabelTrack *pTrack ){ + const auto &labels = pTrack->GetLabels(); + return std::any_of( labels.begin(), labels.end(), + [&](const LabelStruct &label){ + return + label.getT0() >= selectedRegion.t0() + && + label.getT1() <= selectedRegion.t1() + ; + } + ); + }; + auto range = TrackList::Get( project ).Selected() + + test; + return !range.empty(); + } + }, + PlayRegionLockedFlag{ + [](const AudacityProject &project){ + return ViewInfo::Get(project).playRegion.Locked(); + } + }, //msmeyer + PlayRegionNotLockedFlag{ + [](const AudacityProject &project){ + const auto &playRegion = ViewInfo::Get(project).playRegion; + return !playRegion.Locked() && !playRegion.Empty(); + } + }, //msmeyer + WaveTracksExistFlag{ + [](const AudacityProject &project){ + return !TrackList::Get( project ).Any().empty(); + } + }, + NoteTracksExistFlag{ + [](const AudacityProject &project){ + return !TrackList::Get( project ).Any().empty(); + } + }, //gsw + NoteTracksSelectedFlag{ + [](const AudacityProject &project){ + return !TrackList::Get( project ).Selected().empty(); + } + }, //gsw + IsNotSyncLockedFlag{ + [](const AudacityProject &project){ + return !ProjectSettings::Get( project ).IsSyncLocked(); + } + }, //awd + IsSyncLockedFlag{ + [](const AudacityProject &project){ + return ProjectSettings::Get( project ).IsSyncLocked(); + } + }, //awd + NotMinimizedFlag{ + [](const AudacityProject &project){ + const wxWindow *focus = FindProjectFrame( &project ); + if (focus) { + while (focus && focus->GetParent()) + focus = focus->GetParent(); + } + return (focus && + !static_cast(focus)->IsIconized() + ); + }, + CommandFlagOptions{}.QuickTest() + }, // prl + PausedFlag{ + [](const AudacityProject&){ + return AudioIOBase::Get()->IsPaused(); + }, + CommandFlagOptions{}.QuickTest() + }, + PlayableTracksExistFlag{ + [](const AudacityProject &project){ + auto &tracks = TrackList::Get( project ); + return +#ifdef EXPERIMENTAL_MIDI_OUT + !tracks.Any().empty() + || +#endif + !tracks.Any().empty() + ; + } + }, + AudioTracksSelectedFlag{ + [](const AudacityProject &project){ + auto &tracks = TrackList::Get( project ); + return + !tracks.Selected().empty() + // even if not EXPERIMENTAL_MIDI_OUT + || + tracks.Selected().empty() + ; + } + }, + NoAutoSelect{ + [](const AudacityProject &){ return true; } + } // jkc +; + +RegisteredMenuItemEnabler stopIfPaused{{ + PausedFlag, + AudioIONotBusyFlag, + []( const AudacityProject &project ){ + return MenuManager::Get( project ).mStopIfWasPaused; }, + []( AudacityProject &project, CommandFlag ){ + if ( MenuManager::Get( project ).mStopIfWasPaused ) + TransportActions::StopIfPaused( project ); + } +}}; diff --git a/src/CommonCommandFlags.h b/src/CommonCommandFlags.h index e69de29bb..4a73d0c79 100644 --- a/src/CommonCommandFlags.h +++ b/src/CommonCommandFlags.h @@ -0,0 +1,58 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +CommonCommandFlags.cpp + +Paul Licameli split from Menus.cpp + +**********************************************************************/ + +#ifndef __AUDACITY_COMMON_COMMAND_FLAGS__ +#define __AUDACITY_COMMON_COMMAND_FLAGS__ + +#include "commands/CommandFlag.h" + +bool TracksSelectedPred( const AudacityProject &project ); +bool AudioIOBusyPred( const AudacityProject &project ); +bool TimeSelectedPred( const AudacityProject &project ); +extern const CommandFlagOptions cutCopyOptions; + +extern const ReservedCommandFlag + AudioIONotBusyFlag, + StereoRequiredFlag, //lda + TimeSelectedFlag, // This is equivalent to check if there is a valid selection, so it's used for Zoom to Selection too + WaveTracksSelectedFlag, + TracksExistFlag, + TracksSelectedFlag, + TrackPanelHasFocus; //lll + +extern const ReservedCommandFlag + AudioIOBusyFlag, // lll + CaptureNotBusyFlag, + HasWaveDataFlag; // jkc + +extern const ReservedCommandFlag + LabelTracksExistFlag, + UnsavedChangesFlag, + HasLastEffectFlag, + UndoAvailableFlag, + RedoAvailableFlag, + ZoomInAvailableFlag, + ZoomOutAvailableFlag, + LabelsSelectedFlag, + PlayRegionLockedFlag, //msmeyer + PlayRegionNotLockedFlag, //msmeyer + WaveTracksExistFlag, + NoteTracksExistFlag, //gsw + NoteTracksSelectedFlag, //gsw + IsNotSyncLockedFlag, //awd + IsSyncLockedFlag, //awd + NotMinimizedFlag, // prl + PausedFlag, // jkc + PlayableTracksExistFlag, + AudioTracksSelectedFlag, + NoAutoSelect // jkc +; + +#endif diff --git a/src/Menus.cpp b/src/Menus.cpp index bd333a40e..c1274ac95 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -32,27 +32,14 @@ #include -#include "AdornedRulerPanel.h" -#include "AudioIO.h" -#include "LabelTrack.h" #include "ModuleManager.h" -#ifdef USE_MIDI -#include "NoteTrack.h" -#endif // USE_MIDI -#include "Prefs.h" #include "Project.h" -#include "ProjectAudioIO.h" -#include "ProjectFileIO.h" #include "ProjectHistory.h" #include "ProjectSettings.h" #include "ProjectWindow.h" #include "UndoManager.h" -#include "ViewInfo.h" #include "commands/CommandManager.h" -#include "commands/CommandManagerWindowClasses.h" -#include "effects/EffectManager.h" #include "prefs/TracksPrefs.h" -#include "toolbars/ControlToolBar.h" #include "toolbars/ToolManager.h" #include "widgets/ErrorDialog.h" @@ -401,28 +388,6 @@ void MenuManager::OnUndoRedo( wxCommandEvent &evt ) UpdateMenus(); } -// Really means, some track is selected, that isn't a time track -const auto TracksSelectedPred = - [](const AudacityProject &project){ - auto range = TrackList::Get( project ).Selected() - - []( const Track *pTrack ){ - return track_cast( pTrack ); }; - return !range.empty(); - }; - -const auto AudioIOBusyPred = - [](const AudacityProject &project ){ - return AudioIOBase::Get()->IsAudioTokenActive( - ProjectAudioIO::Get( project ).GetAudioIOToken()); - }; - -const auto TimeSelectedPred = - [](const AudacityProject &project){ - // This is equivalent to check if there is a valid selection, - // so it's used for Zoom to Selection too - return !ViewInfo::Get( project ).selectedRegion.isPoint(); - }; - namespace{ using Predicates = std::vector< ReservedCommandFlag::Predicate >; Predicates &RegisteredPredicates() @@ -448,319 +413,6 @@ ReservedCommandFlag::ReservedCommandFlag( Options().emplace_back( options ); } -static const CommandFlagOptions cutCopyOptions{ -// In reporting the issue with cut or copy, we don't tell the user they could also select some text in a label. - []( const wxString &Name ) { - // PRL: These strings have hard-coded mention of a certain shortcut key, - // thus assuming the default shortcuts. That is questionable. - wxString format; -#ifdef EXPERIMENTAL_DA - // i18n-hint: %s will be replaced by the name of an action, such as Normalize, Cut, Fade. - format = _("You must first select some audio for '%s' to act on.\n\nCtrl + A selects all audio."); -#else -#ifdef __WXMAC__ - // i18n-hint: %s will be replaced by the name of an action, such as Normalize, Cut, Fade. - format = _("Select the audio for %s to use (for example, Cmd + A to Select All) then try again." - // No need to explain what a help button is for. - // "\n\nClick the Help button to learn more about selection methods." - ); - -#else - // i18n-hint: %s will be replaced by the name of an action, such as Normalize, Cut, Fade. - format = _("Select the audio for %s to use (for example, Ctrl + A to Select All) then try again." - // No need to explain what a help button is for. - // "\n\nClick the Help button to learn more about selection methods." - ); -#endif - return wxString::Format( format, Name ); -#endif - }, - "Selecting_Audio_-_the_basics", - XO("No Audio Selected") -}; - -const ReservedCommandFlag - // This flag has higher priority than others for purposes of help messages. - // It was important to arrange that for reasons of breaking dependency - // cycles, giving more freedom in the choice of file in which to implement - // this flag. - AudioIONotBusyFlag{ - [](const AudacityProject &project ){ - return !AudioIOBusyPred( project ); - }, - CommandFlagOptions{ []( const wxString& ) { return - // This reason will not be shown, because options that require it will be greyed out. - _("You can only do this when playing and recording are\nstopped. (Pausing is not sufficient.)"); - } } - .QuickTest() - .Priority( 1 ) - }; //lll - -const ReservedCommandFlag - // The sequence of these definitions has a minor significance in determining - // which user error message has precedence if more than one might apply, so - // they should be kept in this sequence in one .cpp file if it is important - // to preserve that behavior. If they are dispersed to more than one file, - // then the precedence will be unspecified. - // The ordering of the flags that only disable the default message is not - // significant. - StereoRequiredFlag{ - [](const AudacityProject &project){ - // True iff at least one stereo track is selected, i.e., at least - // one right channel is selected. - // TODO: more-than-two-channels - auto range = TrackList::Get( project ).Selected() - - &Track::IsLeader; - return !range.empty(); - }, - { []( const wxString& ) { return - // This reason will not be shown, because the stereo-to-mono is greyed out if not allowed. - _("You must first select some stereo audio to perform this\naction. (You cannot use this with mono.)"); - } } - }, //lda - TimeSelectedFlag{ - TimeSelectedPred, - cutCopyOptions - }, - CutCopyAvailableFlag{ - [](const AudacityProject &project){ - auto range = TrackList::Get( project ).Any() - + &LabelTrack::IsTextSelected; - if ( !range.empty() ) - return true; - - if ( - !AudioIOBusyPred( project ) - && - TimeSelectedPred( project ) - && - TracksSelectedPred( project ) - ) - return true; - - return false; - }, - cutCopyOptions - }, - WaveTracksSelectedFlag{ - [](const AudacityProject &project){ - return !TrackList::Get( project ).Selected().empty(); - }, - { []( const wxString& ) { return - _("You must first select some audio to perform this action.\n(Selecting other kinds of track won't work.)"); - } } - }, - TracksExistFlag{ - [](const AudacityProject &project){ - return !TrackList::Get( project ).Any().empty(); - }, - CommandFlagOptions{}.DisableDefaultMessage() - }, - TracksSelectedFlag{ - TracksSelectedPred, - { []( const wxString &Name ){ return wxString::Format( - // i18n-hint: %s will be replaced by the name of an action, such as "Remove Tracks". - _("\"%s\" requires one or more tracks to be selected."), - Name - ); } } - }, - TrackPanelHasFocus{ - [](const AudacityProject &project){ - for (auto w = wxWindow::FindFocus(); w; w = w->GetParent()) { - if (dynamic_cast(w)) - return true; - } - return false; - }, - CommandFlagOptions{}.DisableDefaultMessage() - }; //lll - -const ReservedCommandFlag - LabelTracksExistFlag{ - [](const AudacityProject &project){ - return !TrackList::Get( project ).Any().empty(); - } - }, - UnsavedChangesFlag{ - [](const AudacityProject &project){ - auto &undoManager = UndoManager::Get( project ); - return - undoManager.UnsavedChanges() - || - !ProjectFileIO::Get( project ).IsProjectSaved() - ; - } - }, - HasLastEffectFlag{ - [](const AudacityProject &project){ - return !MenuManager::Get( project ).mLastEffect.empty(); - } - }, - UndoAvailableFlag{ - [](const AudacityProject &project){ - return ProjectHistory::Get( project ).UndoAvailable(); - } - }, - RedoAvailableFlag{ - [](const AudacityProject &project){ - return ProjectHistory::Get( project ).RedoAvailable(); - } - }, - ZoomInAvailableFlag{ - [](const AudacityProject &project){ - return - ViewInfo::Get( project ).ZoomInAvailable() - && - !TrackList::Get( project ).Any().empty() - ; - } - }, - ZoomOutAvailableFlag{ - [](const AudacityProject &project){ - return - ViewInfo::Get( project ).ZoomOutAvailable() - && - !TrackList::Get( project ).Any().empty() - ; - } - }, - LabelsSelectedFlag{ - [](const AudacityProject &project){ - // At least one label track selected, having at least one label - // completely within the time selection. - const auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - const auto &test = [&]( const LabelTrack *pTrack ){ - const auto &labels = pTrack->GetLabels(); - return std::any_of( labels.begin(), labels.end(), - [&](const LabelStruct &label){ - return - label.getT0() >= selectedRegion.t0() - && - label.getT1() <= selectedRegion.t1() - ; - } - ); - }; - auto range = TrackList::Get( project ).Selected() - + test; - return !range.empty(); - } - }, - AudioIOBusyFlag{ - AudioIOBusyPred, - CommandFlagOptions{}.QuickTest() - }, //lll - PlayRegionLockedFlag{ - [](const AudacityProject &project){ - return ViewInfo::Get(project).playRegion.Locked(); - } - }, //msmeyer - PlayRegionNotLockedFlag{ - [](const AudacityProject &project){ - const auto &playRegion = ViewInfo::Get(project).playRegion; - return !playRegion.Locked() && !playRegion.Empty(); - } - }, //msmeyer - WaveTracksExistFlag{ - [](const AudacityProject &project){ - return !TrackList::Get( project ).Any().empty(); - } - }, - NoteTracksExistFlag{ - [](const AudacityProject &project){ - return !TrackList::Get( project ).Any().empty(); - } - }, //gsw - NoteTracksSelectedFlag{ - [](const AudacityProject &project){ - return !TrackList::Get( project ).Selected().empty(); - } - }, //gsw - IsNotSyncLockedFlag{ - [](const AudacityProject &project){ - return !ProjectSettings::Get( project ).IsSyncLocked(); - } - }, //awd - IsSyncLockedFlag{ - [](const AudacityProject &project){ - return ProjectSettings::Get( project ).IsSyncLocked(); - } - }, //awd - IsRealtimeNotActiveFlag{ - [](const AudacityProject &){ - return !EffectManager::Get().RealtimeIsActive(); - } - }, //lll - CaptureNotBusyFlag{ - [](const AudacityProject &){ - auto gAudioIO = AudioIO::Get(); - return !( - gAudioIO->IsBusy() && - gAudioIO->GetNumCaptureChannels() > 0 - ); - } - }, - CanStopAudioStreamFlag{ - [](const AudacityProject &project){ - return ControlToolBar::Get( project ).CanStopAudioStream(); - } - }, - NotMinimizedFlag{ - [](const AudacityProject &project){ - const wxWindow *focus = FindProjectFrame( &project ); - if (focus) { - while (focus && focus->GetParent()) - focus = focus->GetParent(); - } - return (focus && - !static_cast(focus)->IsIconized() - ); - }, - CommandFlagOptions{}.QuickTest() - }, // prl - PausedFlag{ - [](const AudacityProject&){ - return AudioIOBase::Get()->IsPaused(); - }, - CommandFlagOptions{}.QuickTest() - }, - HasWaveDataFlag{ - [](const AudacityProject &project){ - auto range = TrackList::Get( project ).Any() - + [](const WaveTrack *pTrack){ - return pTrack->GetEndTime() > pTrack->GetStartTime(); - }; - return !range.empty(); - } - }, // jkc - PlayableTracksExistFlag{ - [](const AudacityProject &project){ - auto &tracks = TrackList::Get( project ); - return -#ifdef EXPERIMENTAL_MIDI_OUT - !tracks.Any().empty() - || -#endif - !tracks.Any().empty() - ; - } - }, - AudioTracksSelectedFlag{ - [](const AudacityProject &project){ - auto &tracks = TrackList::Get( project ); - return - !tracks.Selected().empty() - // even if not EXPERIMENTAL_MIDI_OUT - || - tracks.Selected().empty() - ; - } - }, - NoAutoSelect{ - [](const AudacityProject &){ return true; } - } // jkc -; - CommandFlag MenuManager::GetUpdateFlags( bool checkActive ) { // This method determines all of the flags that determine whether @@ -898,39 +550,6 @@ RegisteredMenuItemEnabler::RegisteredMenuItemEnabler( Enablers().emplace_back( enabler ); } -RegisteredMenuItemEnabler stopIfPaused{{ - PausedFlag, - AudioIONotBusyFlag, - []( const AudacityProject &project ){ - return MenuManager::Get( project ).mStopIfWasPaused; }, - []( AudacityProject &project, CommandFlag ){ - if ( MenuManager::Get( project ).mStopIfWasPaused ) - TransportActions::StopIfPaused( project ); - } -}}; - -auto canSelectAll = [](const AudacityProject &project){ - return MenuManager::Get( project ).mWhatIfNoSelection != 0; }; -auto selectAll = []( AudacityProject &project, CommandFlag flagsRqd ){ - if ( MenuManager::Get( project ).mWhatIfNoSelection == 1 && - (flagsRqd & NoAutoSelect).none() ) - SelectActions::DoSelectAllAudio(project); -}; - -RegisteredMenuItemEnabler selectTracks{{ - TracksExistFlag, - TracksSelectedFlag, - canSelectAll, - selectAll -}}; - -RegisteredMenuItemEnabler selectWaveTracks{{ - WaveTracksExistFlag, - TimeSelectedFlag | WaveTracksSelectedFlag | CutCopyAvailableFlag, - canSelectAll, - selectAll -}}; - // checkActive is a temporary hack that should be removed as soon as we // get multiple effect preview working void MenuManager::UpdateMenus( bool checkActive ) diff --git a/src/commands/CommandFlag.h b/src/commands/CommandFlag.h index 784dd5039..75cb4acf7 100644 --- a/src/commands/CommandFlag.h +++ b/src/commands/CommandFlag.h @@ -94,43 +94,6 @@ public: // extended, with special purpose flags of limited use, by constucting static // ReservedCommandFlag values -extern const ReservedCommandFlag - AudioIOBusyFlag, //lll - StereoRequiredFlag, //lda - TimeSelectedFlag, // This is equivalent to check if there is a valid selection, so it's used for Zoom to Selection too - CutCopyAvailableFlag, - WaveTracksSelectedFlag, - TracksExistFlag, - TracksSelectedFlag, - TrackPanelHasFocus, //lll - - AudioIONotBusyFlag, - LabelTracksExistFlag, - UnsavedChangesFlag, - HasLastEffectFlag, - UndoAvailableFlag, - RedoAvailableFlag, - ZoomInAvailableFlag, - ZoomOutAvailableFlag, - LabelsSelectedFlag, - PlayRegionLockedFlag, //msmeyer - PlayRegionNotLockedFlag, //msmeyer - WaveTracksExistFlag, - NoteTracksExistFlag, //gsw - NoteTracksSelectedFlag, //gsw - IsNotSyncLockedFlag, //awd - IsSyncLockedFlag, //awd - IsRealtimeNotActiveFlag, //lll - CaptureNotBusyFlag, - CanStopAudioStreamFlag, - NotMinimizedFlag, // prl - PausedFlag, // jkc - HasWaveDataFlag, // jkc - PlayableTracksExistFlag, - AudioTracksSelectedFlag, - NoAutoSelect // jkc -; - // To describe auto-selection, stop-if-paused, etc.: // A structure describing a set of conditions, another set that might be // made true given the first, and the function that may make them true. diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index bb22da2a2..904860299 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -49,6 +49,7 @@ greater use in future. #include "EffectManager.h" #include "../AudioIO.h" +#include "../CommonCommandFlags.h" #include "../LabelTrack.h" #include "../Menus.h" #include "../Mix.h" @@ -57,7 +58,6 @@ greater use in future. #include "../Project.h" #include "../ProjectAudioManager.h" #include "../ProjectSettings.h" -#include "../PluginManager.h" #include "../ShuttleGui.h" #include "../Shuttle.h" #include "../ViewInfo.h" diff --git a/src/menus/ClipMenus.cpp b/src/menus/ClipMenus.cpp index 2068c1545..c94de4b79 100644 --- a/src/menus/ClipMenus.cpp +++ b/src/menus/ClipMenus.cpp @@ -1,3 +1,4 @@ +#include "../CommonCommandFlags.h" #include "../ProjectHistory.h" #include "../ProjectSettings.h" #include "../TrackPanel.h" diff --git a/src/menus/EditMenus.cpp b/src/menus/EditMenus.cpp index b82050116..a807361eb 100644 --- a/src/menus/EditMenus.cpp +++ b/src/menus/EditMenus.cpp @@ -1,6 +1,7 @@ #include "../Audacity.h" // for USE_* macros #include "../AdornedRulerPanel.h" #include "../Clipboard.h" +#include "../CommonCommandFlags.h" #include "../LabelTrack.h" #include "../Menus.h" #include "../NoteTrack.h" @@ -1090,6 +1091,28 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) { MenuTable::BaseItemPtr LabelEditMenus( AudacityProject &project ); +const ReservedCommandFlag + CutCopyAvailableFlag{ + [](const AudacityProject &project){ + auto range = TrackList::Get( project ).Any() + + &LabelTrack::IsTextSelected; + if ( !range.empty() ) + return true; + + if ( + !AudioIOBusyPred( project ) + && + TimeSelectedPred( project ) + && + TracksSelectedPred( project ) + ) + return true; + + return false; + }, + cutCopyOptions + }; + MenuTable::BaseItemPtr EditMenu( AudacityProject & ) { using namespace MenuTable; @@ -1229,5 +1252,27 @@ MenuTable::BaseItemPtr ExtraEditMenu( AudacityProject & ) ); } +auto canSelectAll = [](const AudacityProject &project){ + return MenuManager::Get( project ).mWhatIfNoSelection != 0; }; +auto selectAll = []( AudacityProject &project, CommandFlag flagsRqd ){ + if ( MenuManager::Get( project ).mWhatIfNoSelection == 1 && + (flagsRqd & NoAutoSelect).none() ) + SelectActions::DoSelectAllAudio(project); +}; + +RegisteredMenuItemEnabler selectTracks{{ + TracksExistFlag, + TracksSelectedFlag, + canSelectAll, + selectAll +}}; + +RegisteredMenuItemEnabler selectWaveTracks{{ + WaveTracksExistFlag, + TimeSelectedFlag | WaveTracksSelectedFlag | CutCopyAvailableFlag, + canSelectAll, + selectAll +}}; + #undef XXO #undef FN diff --git a/src/menus/ExtraMenus.cpp b/src/menus/ExtraMenus.cpp index 11bb81227..a33dd61bf 100644 --- a/src/menus/ExtraMenus.cpp +++ b/src/menus/ExtraMenus.cpp @@ -1,3 +1,4 @@ +#include "../CommonCommandFlags.h" #include "../Prefs.h" #include "../Project.h" #include "../commands/CommandContext.h" diff --git a/src/menus/FileMenus.cpp b/src/menus/FileMenus.cpp index 20b03e8cc..9cf784fd9 100644 --- a/src/menus/FileMenus.cpp +++ b/src/menus/FileMenus.cpp @@ -2,6 +2,7 @@ #include "../Experimental.h" #include "../BatchCommands.h" +#include "../CommonCommandFlags.h" #include "../FileNames.h" #include "../LabelTrack.h" #include "../MissingAliasFileDialog.h" diff --git a/src/menus/HelpMenus.cpp b/src/menus/HelpMenus.cpp index 3320e126f..e9d0577b6 100644 --- a/src/menus/HelpMenus.cpp +++ b/src/menus/HelpMenus.cpp @@ -9,6 +9,7 @@ #include "../AllThemeResources.h" #include "../AudacityLogger.h" #include "../AudioIOBase.h" +#include "../CommonCommandFlags.h" #include "../CrashReport.h" #include "../Dependencies.h" #include "../FileNames.h" diff --git a/src/menus/LabelMenus.cpp b/src/menus/LabelMenus.cpp index 7b2dd4a23..26b300810 100644 --- a/src/menus/LabelMenus.cpp +++ b/src/menus/LabelMenus.cpp @@ -1,5 +1,6 @@ #include "../AudioIOBase.h" #include "../Clipboard.h" +#include "../CommonCommandFlags.h" #include "../LabelTrack.h" #include "../Menus.h" #include "../Prefs.h" diff --git a/src/menus/NavigationMenus.cpp b/src/menus/NavigationMenus.cpp index 045fc743b..a9d07cccc 100644 --- a/src/menus/NavigationMenus.cpp +++ b/src/menus/NavigationMenus.cpp @@ -1,5 +1,6 @@ #include "../Audacity.h" +#include "../CommonCommandFlags.h" #include "../Menus.h" #include "../Prefs.h" #include "../Project.h" diff --git a/src/menus/PluginMenus.cpp b/src/menus/PluginMenus.cpp index 26383e2db..c10bf4098 100644 --- a/src/menus/PluginMenus.cpp +++ b/src/menus/PluginMenus.cpp @@ -4,6 +4,7 @@ #include "../AudioIO.h" #include "../BatchProcessDialog.h" #include "../Benchmark.h" +#include "../CommonCommandFlags.h" #include "../FreqWindow.h" #include "../Menus.h" #include "../MissingAliasFileDialog.h" @@ -923,6 +924,13 @@ MenuTable::BaseItemPtr GenerateMenu( AudacityProject & ) ); } +const ReservedCommandFlag + IsRealtimeNotActiveFlag{ + [](const AudacityProject &){ + return !EffectManager::Get().RealtimeIsActive(); + } + }; //lll + MenuTable::BaseItemPtr EffectMenu( AudacityProject &project ) { using namespace MenuTable; diff --git a/src/menus/SelectMenus.cpp b/src/menus/SelectMenus.cpp index ad2c63dfc..34a7f8263 100644 --- a/src/menus/SelectMenus.cpp +++ b/src/menus/SelectMenus.cpp @@ -3,6 +3,7 @@ #include "../AdornedRulerPanel.h" #include "../AudioIO.h" +#include "../CommonCommandFlags.h" #include "../FreqWindow.h" #include "../Menus.h" // for PrefsListener #include "../Prefs.h" diff --git a/src/menus/TrackMenus.cpp b/src/menus/TrackMenus.cpp index 261ad06f1..9074a0319 100644 --- a/src/menus/TrackMenus.cpp +++ b/src/menus/TrackMenus.cpp @@ -1,6 +1,7 @@ #include "../Audacity.h" #include "../Experimental.h" +#include "../CommonCommandFlags.h" #include "../LabelTrack.h" #include "../Menus.h" #include "../MissingAliasFileDialog.h" diff --git a/src/menus/TransportMenus.cpp b/src/menus/TransportMenus.cpp index f1a600c6e..c0689c090 100644 --- a/src/menus/TransportMenus.cpp +++ b/src/menus/TransportMenus.cpp @@ -3,6 +3,7 @@ #include "../AdornedRulerPanel.h" #include "../AudioIO.h" +#include "../CommonCommandFlags.h" #include "../DeviceManager.h" #include "../LabelTrack.h" #include "../Menus.h" diff --git a/src/menus/ViewMenus.cpp b/src/menus/ViewMenus.cpp index 98584a22b..c78a3f4ae 100644 --- a/src/menus/ViewMenus.cpp +++ b/src/menus/ViewMenus.cpp @@ -1,6 +1,7 @@ #include "../Audacity.h" #include "../Experimental.h" +#include "../CommonCommandFlags.h" #include "../HistoryWindow.h" #include "../LyricsWindow.h" #include "../Menus.h" diff --git a/src/menus/WindowMenus.cpp b/src/menus/WindowMenus.cpp index f75b82474..7da14a17d 100644 --- a/src/menus/WindowMenus.cpp +++ b/src/menus/WindowMenus.cpp @@ -7,6 +7,7 @@ #ifdef __WXMAC__ +#include "../CommonCommandFlags.h" #include "../Menus.h" #include "../Project.h" #include "../commands/CommandContext.h" diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index b455f28f4..983914d8c 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -60,6 +60,7 @@ #include "../AdornedRulerPanel.h" #include "../AllThemeResources.h" #include "../AudioIO.h" +#include "../CommonCommandFlags.h" #include "../ImageManipulation.h" #include "../Menus.h" #include "../Prefs.h" @@ -1562,3 +1563,10 @@ static RegisteredToolbarFactory factory{ TransportBarID, []( AudacityProject &project ){ return ToolBar::Holder{ safenew ControlToolBar{ project } }; } }; + +const ReservedCommandFlag + CanStopAudioStreamFlag{ + [](const AudacityProject &project){ + return ControlToolBar::Get( project ).CanStopAudioStream(); + } + }; diff --git a/src/toolbars/ControlToolBar.h b/src/toolbars/ControlToolBar.h index d4d438490..13ff7bd9b 100644 --- a/src/toolbars/ControlToolBar.h +++ b/src/toolbars/ControlToolBar.h @@ -210,5 +210,10 @@ class ControlToolBar final : public ToolBar { DECLARE_EVENT_TABLE() }; +#include "../commands/CommandFlag.h" + +extern const ReservedCommandFlag + CanStopAudioStreamFlag; + #endif diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index afaf6b5fd..d55779abd 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -17,6 +17,7 @@ Paul Licameli split from TrackPanel.cpp #include "../../AdornedRulerPanel.h" #include "../../AudioIO.h" +#include "../../CommonCommandFlags.h" #include "../../Menus.h" #include "../../Project.h" #include "../../ProjectAudioIO.h"