1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-14 07:20:35 +02:00

Move menu handling functions out of class AudacityProject

This commit is contained in:
Paul Licameli 2017-08-20 00:16:22 -04:00
parent 3ed43a9f12
commit 9481587fa8
30 changed files with 2949 additions and 1913 deletions

View File

@ -1402,7 +1402,7 @@ void NyqBench::OnGo(wxCommandEvent & e)
mRunning = true; mRunning = true;
UpdateWindowUI(); UpdateWindowUI();
p->DoEffect(ID, CommandContext(*p), 0); GetMenuCommandHandler(*p).DoEffect(ID, CommandContext(*p), 0);
mRunning = false; mRunning = false;
UpdateWindowUI(); UpdateWindowUI();

View File

@ -1593,7 +1593,7 @@ bool AudacityApp::OnInit()
// Mainly this is to tell users of ALPHAS who don't know that they have an ALPHA. // Mainly this is to tell users of ALPHAS who don't know that they have an ALPHA.
// Disabled for now, after discussion. // Disabled for now, after discussion.
// project->MayCheckForUpdates(); // project->MayCheckForUpdates();
project->OnHelpWelcome(*project); GetMenuCommandHandler(*project).OnHelpWelcome(*project);
} }
// JKC 10-Sep-2007: Enable monitoring from the start. // JKC 10-Sep-2007: Enable monitoring from the start.
@ -1686,7 +1686,7 @@ void AudacityApp::OnKeyDown(wxKeyEvent &event)
gAudioIO->GetNumCaptureChannels() == 0) || gAudioIO->GetNumCaptureChannels() == 0) ||
scrubbing) scrubbing)
// ESC out of other play (but not record) // ESC out of other play (but not record)
project->OnStop(*project); GetMenuCommandHandler(*project).OnStop(*project);
else else
event.Skip(); event.Skip();
} }

View File

@ -730,18 +730,18 @@ bool MacroCommands::ApplyEffectCommand(
{ {
if( plug->GetPluginType() == PluginTypeAudacityCommand ) if( plug->GetPluginType() == PluginTypeAudacityCommand )
// and apply the effect... // and apply the effect...
res = project->DoAudacityCommand(ID, res = GetMenuCommandHandler(*project).DoAudacityCommand(ID,
Context, Context,
AudacityProject::OnEffectFlags::kConfigured | MenuCommandHandler::OnEffectFlags::kConfigured |
AudacityProject::OnEffectFlags::kSkipState | MenuCommandHandler::OnEffectFlags::kSkipState |
AudacityProject::OnEffectFlags::kDontRepeatLast); MenuCommandHandler::OnEffectFlags::kDontRepeatLast);
else else
// and apply the effect... // and apply the effect...
res = project->DoEffect(ID, res = GetMenuCommandHandler(*project).DoEffect(ID,
Context, Context,
AudacityProject::OnEffectFlags::kConfigured | MenuCommandHandler::OnEffectFlags::kConfigured |
AudacityProject::OnEffectFlags::kSkipState | MenuCommandHandler::OnEffectFlags::kSkipState |
AudacityProject::OnEffectFlags::kDontRepeatLast); MenuCommandHandler::OnEffectFlags::kDontRepeatLast);
} }
return res; return res;
@ -802,7 +802,7 @@ bool MacroCommands::ApplyCommandInBatchMode( const wxString &friendlyCommand,
{ {
AudacityProject *project = GetActiveProject(); AudacityProject *project = GetActiveProject();
// Recalc flags and enable items that may have become enabled. // Recalc flags and enable items that may have become enabled.
project->UpdateMenus(false); GetMenuCommandHandler(*project).UpdateMenus(*project, false);
// enter batch mode... // enter batch mode...
bool prevShowMode = project->GetShowId3Dialog(); bool prevShowMode = project->GetShowId3Dialog();
project->mBatchMode++; project->mBatchMode++;

View File

@ -461,7 +461,7 @@ void ApplyMacroDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event))
auto success = GuardedCall< bool >( [&] { auto success = GuardedCall< bool >( [&] {
project->Import(files[i]); project->Import(files[i]);
project->ZoomAfterImport(nullptr); project->ZoomAfterImport(nullptr);
project->OnSelectAll(*project); GetMenuCommandHandler(*project).OnSelectAll(*project);
if (!mMacroCommands.ApplyMacro(mCatalog)) if (!mMacroCommands.ApplyMacro(mCatalog))
return false; return false;
@ -476,6 +476,7 @@ void ApplyMacroDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event))
project->ResetProjectToEmpty(); project->ResetProjectToEmpty();
} }
Show(); Show();
Raise(); Raise();
} }
@ -747,7 +748,8 @@ void MacrosWindow::AddItem(const wxString &Action, const wxString &Params)
void MacrosWindow::UpdateMenus() void MacrosWindow::UpdateMenus()
{ {
// OK even on mac, as dialog is modal. // OK even on mac, as dialog is modal.
GetActiveProject()->RebuildMenuBar(); auto p = GetActiveProject();
GetMenuCommandHandler(*p).RebuildMenuBar(*p);
} }
void MacrosWindow::UpdateDisplay( bool bExpanded ) void MacrosWindow::UpdateDisplay( bool bExpanded )

View File

@ -2103,7 +2103,8 @@ bool LabelTrack::OnChar(SelectedRegion &WXUNUSED(newSel), wxKeyEvent & event)
gPrefs->Read(wxT("/Gui/DialogForNameNewLabel"), &useDialog, false); gPrefs->Read(wxT("/Gui/DialogForNameNewLabel"), &useDialog, false);
if (useDialog) { if (useDialog) {
wxString title; wxString title;
if (p->DialogForLabelName(charCode, title) == wxID_CANCEL) { if (MenuCommandHandler::DialogForLabelName(*p, charCode, title) ==
wxID_CANCEL) {
return false; return false;
} }
SetSelected(true); SetSelected(true);
@ -2239,7 +2240,7 @@ void LabelTrack::OnContextMenu(wxCommandEvent & evt)
case OnEditSelectedLabelID: { case OnEditSelectedLabelID: {
int ndx = GetLabelIndex(p->GetSel0(), p->GetSel1()); int ndx = GetLabelIndex(p->GetSel0(), p->GetSel1());
if (ndx != -1) if (ndx != -1)
p->DoEditLabels(this, ndx); GetMenuCommandHandler(*p).DoEditLabels(*p, this, ndx);
} }
break; break;
} }

File diff suppressed because it is too large Load Diff

View File

@ -10,21 +10,24 @@
#ifndef __AUDACITY_MENUS__ #ifndef __AUDACITY_MENUS__
#define __AUDACITY_MENUS__ #define __AUDACITY_MENUS__
// Formerly members of AudacityProject, now members of MenuCommandHandler
#include "Experimental.h" #include "Experimental.h"
// Command Handling
bool ReportIfActionNotAllowed
( AudacityProject &project,
const wxString & Name, CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask );
bool TryToMakeActionAllowed
( AudacityProject &project,
CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask );
// These are all member functions of class AudacityProject. void UpdatePrefs();
// Vaughan, 2010-08-05:
// Note that this file is included in a "public" section of Project.h.
// Most of these methods do not need to be public, and because
// we do not subclass AudacityProject, they should be "private."
// Because the ones that need to be public are intermixed,
// I've added "private" in just a few cases.
private: void CreateMenusAndCommands(AudacityProject &project);
void CreateMenusAndCommands();
void PopulateMacrosMenu( CommandManager* c, CommandFlag flags ); void PopulateMacrosMenu( CommandManager* c, CommandFlag flags );
void PopulateEffectsMenu(CommandManager *c, EffectType type, void PopulateEffectsMenu(CommandManager *c, EffectType type,
CommandFlag batchflags, CommandFlag realflags); CommandFlag batchflags, CommandFlag realflags);
void AddEffectMenuItems(CommandManager *c, void AddEffectMenuItems(CommandManager *c,
@ -35,28 +38,36 @@ void AddEffectMenuItemGroup(CommandManager *c, const wxArrayString & names,
const PluginIDList & plugs, const PluginIDList & plugs,
const std::vector<CommandFlag> & flags, bool isDefault); const std::vector<CommandFlag> & flags, bool isDefault);
void CreateRecentFilesMenu(CommandManager *c); void CreateRecentFilesMenu(CommandManager *c);
void ModifyUndoMenuItems(); void ModifyUndoMenuItems(AudacityProject &project);
void ModifyToolbarMenus(); void ModifyToolbarMenus(AudacityProject &project);
void RebuildMenuBar(AudacityProject &project);
// Calls ModifyToolbarMenus() on all projects // Calls ModifyToolbarMenus() on all projects
void ModifyAllProjectToolbarMenus(); void ModifyAllProjectToolbarMenus();
CommandFlag GetFocusedFrame(); // checkActive is a temporary hack that should be removed as soon as we
// get multiple effect preview working
void UpdateMenus(AudacityProject &project, bool checkActive = true);
CommandFlag GetFocusedFrame(AudacityProject &project);
public:
// If checkActive, do not do complete flags testing on an // If checkActive, do not do complete flags testing on an
// inactive project as it is needlessly expensive. // inactive project as it is needlessly expensive.
CommandFlag GetUpdateFlags(bool checkActive = false); CommandFlag GetUpdateFlags(AudacityProject &project, bool checkActive = false);
//Adds label and returns index of label in labeltrack. //Adds label and returns index of label in labeltrack.
int DoAddLabel(const SelectedRegion& region, bool preserveFocus = false); int DoAddLabel(
int DialogForLabelName(const wxString& initialValue, wxString& value); AudacityProject &project,
const SelectedRegion& region, bool preserveFocus = false);
static int DialogForLabelName(
AudacityProject &project, const wxString& initialValue, wxString& value);
private:
double NearestZeroCrossing(double t0); double NearestZeroCrossing(AudacityProject &project, double t0);
// Selecting a tool from the keyboard // Selecting a tool from the keyboard
void SetTool(int tool); void SetTool(AudacityProject &project, int tool);
void OnSelectTool(const CommandContext &context ); void OnSelectTool(const CommandContext &context );
void OnZoomTool(const CommandContext &context ); void OnZoomTool(const CommandContext &context );
void OnEnvelopeTool(const CommandContext &context ); void OnEnvelopeTool(const CommandContext &context );
@ -67,7 +78,7 @@ void OnMultiTool(const CommandContext &context );
void OnNextTool(const CommandContext &context ); void OnNextTool(const CommandContext &context );
void OnPrevTool(const CommandContext &context ); void OnPrevTool(const CommandContext &context );
public:
// Audio I/O Commands // Audio I/O Commands
void OnStop(const CommandContext &context ); void OnStop(const CommandContext &context );
@ -84,9 +95,10 @@ void OnSeekRightLong(const CommandContext &context );
// Different posibilities for playing sound // Different posibilities for playing sound
bool MakeReadyToPlay(bool loop = false, bool cutpreview = false); // Helper function that sets button states etc. bool MakeReadyToPlay(AudacityProject &project,
bool loop = false, bool cutpreview = false); // Helper function that sets button states etc.
void OnPlayStop(const CommandContext &context ); void OnPlayStop(const CommandContext &context );
bool DoPlayStopSelect(bool click, bool shift); bool DoPlayStopSelect(AudacityProject &project, bool click, bool shift);
void OnPlayStopSelect(const CommandContext &context ); void OnPlayStopSelect(const CommandContext &context );
void OnPlayOneSecond(const CommandContext &context ); void OnPlayOneSecond(const CommandContext &context );
void OnPlayToSelection(const CommandContext &context ); void OnPlayToSelection(const CommandContext &context );
@ -117,7 +129,7 @@ void OnTrackMoveTop(const CommandContext &context );
void OnTrackMoveBottom(const CommandContext &context ); void OnTrackMoveBottom(const CommandContext &context );
enum MoveChoice { OnMoveUpID, OnMoveDownID, OnMoveTopID, OnMoveBottomID }; enum MoveChoice { OnMoveUpID, OnMoveDownID, OnMoveTopID, OnMoveBottomID };
void MoveTrack(Track* target, MoveChoice choice); void MoveTrack(AudacityProject &project, Track* target, MoveChoice choice);
// Device control // Device control
void OnInputDevice(const CommandContext &context ); void OnInputDevice(const CommandContext &context );
@ -145,8 +157,8 @@ void OnPlaySpeedDec(const CommandContext &context );
// Moving track focus commands // Moving track focus commands
void OnPrevTrack( bool shift ); void OnPrevTrack( AudacityProject &project, bool shift );
void OnNextTrack( bool shift ); void OnNextTrack( AudacityProject &project, bool shift );
void OnCursorUp(const CommandContext &context ); void OnCursorUp(const CommandContext &context );
void OnCursorDown(const CommandContext &context ); void OnCursorDown(const CommandContext &context );
void OnFirstTrack(const CommandContext &context ); void OnFirstTrack(const CommandContext &context );
@ -158,7 +170,8 @@ void OnShiftUp(const CommandContext &context );
void OnShiftDown(const CommandContext &context ); void OnShiftDown(const CommandContext &context );
void OnToggle(const CommandContext &context ); void OnToggle(const CommandContext &context );
void HandleListSelection(Track *t, bool shift, bool ctrl, bool modifyState); void HandleListSelection(
AudacityProject &project, Track *t, bool shift, bool ctrl, bool modifyState);
void OnCursorLeft(const CommandContext &context ); void OnCursorLeft(const CommandContext &context );
void OnCursorRight(const CommandContext &context ); void OnCursorRight(const CommandContext &context );
@ -167,12 +180,12 @@ void OnSelExtendRight(const CommandContext &context );
void OnSelContractLeft(const CommandContext &context ); void OnSelContractLeft(const CommandContext &context );
void OnSelContractRight(const CommandContext &context ); void OnSelContractRight(const CommandContext &context );
public:
static double OnClipMove static double OnClipMove
(ViewInfo &viewInfo, Track *track, (ViewInfo &viewInfo, Track *track,
TrackList &trackList, bool syncLocked, bool right); TrackList &trackList, bool syncLocked, bool right);
void DoClipLeftOrRight(bool right, bool keyUp ); void DoClipLeftOrRight(AudacityProject &project, bool right, bool keyUp );
void OnClipLeft(const CommandContext &context ); void OnClipLeft(const CommandContext &context );
void OnClipRight(const CommandContext &context ); void OnClipRight(const CommandContext &context );
@ -191,14 +204,14 @@ void OnSelToEnd(const CommandContext &context );
void OnMoveToNextLabel(const CommandContext &context ); void OnMoveToNextLabel(const CommandContext &context );
void OnMoveToPrevLabel(const CommandContext &context ); void OnMoveToPrevLabel(const CommandContext &context );
void OnMoveToLabel(bool next); void OnMoveToLabel(AudacityProject &project, bool next);
void OnZeroCrossing(const CommandContext &context ); void OnZeroCrossing(const CommandContext &context );
void OnLockPlayRegion(const CommandContext &context ); void OnLockPlayRegion(const CommandContext &context );
void OnUnlockPlayRegion(const CommandContext &context ); void OnUnlockPlayRegion(const CommandContext &context );
double GetTime(const Track *t); static double GetTime(const Track *t);
void OnSortTime(const CommandContext &context ); void OnSortTime(const CommandContext &context );
void OnSortName(const CommandContext &context ); void OnSortName(const CommandContext &context );
@ -228,7 +241,7 @@ void OnSaveCopy(const CommandContext &context );
void OnCheckDependencies(const CommandContext &context ); void OnCheckDependencies(const CommandContext &context );
void OnExport(const wxString & Format); void OnExport(AudacityProject &project, const wxString & Format);
void OnExportAudio(const CommandContext &context ); void OnExportAudio(const CommandContext &context );
void OnExportMp3(const CommandContext &context ); void OnExportMp3(const CommandContext &context );
void OnExportWav(const CommandContext &context ); void OnExportWav(const CommandContext &context );
@ -248,24 +261,24 @@ void OnExit(const CommandContext &context );
// Edit Menu // Edit Menu
public:
void OnUndo(const CommandContext &context ); void OnUndo(const CommandContext &context );
void OnRedo(const CommandContext &context ); void OnRedo(const CommandContext &context );
private:
static void FinishCopy(const Track *n, Track *dest); static void FinishCopy(const Track *n, Track *dest);
static void FinishCopy(const Track *n, Track::Holder &&dest, TrackList &list); static void FinishCopy
(const Track *n, Track::Holder &&dest, TrackList &list);
public:
void OnCut(const CommandContext &context ); void OnCut(const CommandContext &context );
void OnSplitCut(const CommandContext &context ); void OnSplitCut(const CommandContext &context );
void OnCopy(const CommandContext &context ); void OnCopy(const CommandContext &context );
void OnPaste(const CommandContext &context ); void OnPaste(const CommandContext &context );
private:
bool HandlePasteText(); // Handle text paste (into active label), if any. Return true if pasted. bool HandlePasteText(AudacityProject &project); // Handle text paste (into active label), if any. Return true if pasted.
bool HandlePasteNothingSelected(); // Return true if nothing selected, regardless of paste result. bool HandlePasteNothingSelected(AudacityProject &project); // Return true if nothing selected, regardless of paste result.
public:
void OnPasteNewLabel(const CommandContext &context ); void OnPasteNewLabel(const CommandContext &context );
void OnPasteOver(const CommandContext &context ); void OnPasteOver(const CommandContext &context );
@ -291,21 +304,24 @@ void OnSplitLabels(const CommandContext &context );
void OnJoinLabels(const CommandContext &context ); void OnJoinLabels(const CommandContext &context );
void OnDisjoinLabels(const CommandContext &context ); void OnDisjoinLabels(const CommandContext &context );
void OnSelectTimeAndTracks(bool bAllTime, bool bAllTracks); void OnSelectTimeAndTracks
(AudacityProject &project, bool bAllTime, bool bAllTracks);
void OnSelectAllTime(const CommandContext &context ); void OnSelectAllTime(const CommandContext &context );
void OnSelectAllTracks(const CommandContext &context ); void OnSelectAllTracks(const CommandContext &context );
void OnSelectAll(const CommandContext &context ); void OnSelectAll(const CommandContext &context );
void OnSelectSomething(const CommandContext &context ); void OnSelectSomething(const CommandContext &context );
void OnSelectNone(const CommandContext &context ); void OnSelectNone(const CommandContext &context );
private: private:
int CountSelectedTracks(); static int CountSelectedTracks(TrackList &tracks);
public: public:
#ifdef EXPERIMENTAL_SPECTRAL_EDITING #ifdef EXPERIMENTAL_SPECTRAL_EDITING
// For toggling of spectral seletion // For toggling of spectral seletion
double mLastF0; double mLastF0{ SelectedRegion::UndefinedFrequency };
double mLastF1; double mLastF1{ SelectedRegion::UndefinedFrequency };
void OnToggleSpectralSelection(const CommandContext &context ); void OnToggleSpectralSelection(const CommandContext &context );
void DoNextPeakFrequency(bool up); void DoNextPeakFrequency(AudacityProject &project, bool up);
void OnNextHigherPeakFrequency(const CommandContext &context ); void OnNextHigherPeakFrequency(const CommandContext &context );
void OnNextLowerPeakFrequency(const CommandContext &context ); void OnNextLowerPeakFrequency(const CommandContext &context );
#endif #endif
@ -314,7 +330,7 @@ void OnSelectStartCursor(const CommandContext &context );
void OnSelectTrackStartToEnd(const CommandContext &context ); void OnSelectTrackStartToEnd(const CommandContext &context );
void OnSelectPrevClipBoundaryToCursor(const CommandContext &context ); void OnSelectPrevClipBoundaryToCursor(const CommandContext &context );
void OnSelectCursorToNextClipBoundary(const CommandContext &context ); void OnSelectCursorToNextClipBoundary(const CommandContext &context );
void OnSelectClipBoundary(bool next); void OnSelectClipBoundary(AudacityProject &project, bool next);
struct FoundTrack { struct FoundTrack {
const WaveTrack* waveTrack{}; const WaveTrack* waveTrack{};
int trackNum{}; int trackNum{};
@ -328,13 +344,18 @@ struct FoundClip : FoundTrack {
double endTime{}; double endTime{};
int index{}; int index{};
}; };
FoundClip FindNextClip(const WaveTrack* wt, double t0, double t1);
FoundClip FindPrevClip(const WaveTrack* wt, double t0, double t1); FoundClip FindNextClip
int FindClips(double t0, double t1, bool next, std::vector<FoundClip>& results); (AudacityProject &project, const WaveTrack* wt, double t0, double t1);
FoundClip FindPrevClip
(AudacityProject &project, const WaveTrack* wt, double t0, double t1);
int FindClips
(AudacityProject &project,
double t0, double t1, bool next, std::vector<FoundClip>& results);
bool ChannelsHaveSameClipBoundaries(const WaveTrack* wt); bool ChannelsHaveSameClipBoundaries(const WaveTrack* wt);
void OnSelectPrevClip(const CommandContext &context ); void OnSelectPrevClip(const CommandContext &context );
void OnSelectNextClip(const CommandContext &context ); void OnSelectNextClip(const CommandContext &context );
void OnSelectClip(bool next); void OnSelectClip(AudacityProject &project, bool next);
void OnSelectCursorStoredCursor(const CommandContext &context ); void OnSelectCursorStoredCursor(const CommandContext &context );
void OnSelectSyncLockSel(const CommandContext &context ); void OnSelectSyncLockSel(const CommandContext &context );
@ -344,7 +365,7 @@ void OnZoomToggle(const CommandContext &context );
void OnZoomNormal(const CommandContext &context ); void OnZoomNormal(const CommandContext &context );
void OnZoomFit(const CommandContext &context ); void OnZoomFit(const CommandContext &context );
void OnZoomFitV(const CommandContext &context ); void OnZoomFitV(const CommandContext &context );
void DoZoomFitV(); void DoZoomFitV(AudacityProject &project);
void OnZoomSel(const CommandContext &context ); void OnZoomSel(const CommandContext &context );
void OnGoSelStart(const CommandContext &context ); void OnGoSelStart(const CommandContext &context );
void OnGoSelEnd(const CommandContext &context ); void OnGoSelEnd(const CommandContext &context );
@ -352,7 +373,7 @@ void OnGoSelEnd(const CommandContext &context );
void OnExpandAllTracks(const CommandContext &context ); void OnExpandAllTracks(const CommandContext &context );
void OnCollapseAllTracks(const CommandContext &context ); void OnCollapseAllTracks(const CommandContext &context );
void OnPanTracks(float PanValue); void OnPanTracks(AudacityProject &project, float PanValue);
void OnPanLeft(const CommandContext &context ); void OnPanLeft(const CommandContext &context );
void OnPanRight(const CommandContext &context ); void OnPanRight(const CommandContext &context );
void OnPanCenter(const CommandContext &context ); void OnPanCenter(const CommandContext &context );
@ -420,17 +441,18 @@ static AudacityProject *DoImportMIDI(
void OnImportRaw(const CommandContext &context ); void OnImportRaw(const CommandContext &context );
void OnEditMetadata(const CommandContext &context ); void OnEditMetadata(const CommandContext &context );
bool DoEditMetadata(const wxString &title, const wxString &shortUndoDescription, bool force); bool DoEditMetadata(AudacityProject &project,
const wxString &title, const wxString &shortUndoDescription, bool force);
void OnMixAndRender(const CommandContext &context ); void OnMixAndRender(const CommandContext &context );
void OnMixAndRenderToNewTrack(const CommandContext &context ); void OnMixAndRenderToNewTrack(const CommandContext &context );
void HandleMixAndRender(bool toNewTrack); void HandleMixAndRender(AudacityProject &project, bool toNewTrack);
private:
SelectedRegion mRegionSave{}; SelectedRegion mRegionSave{};
bool mCursorPositionHasBeenStored{false}; bool mCursorPositionHasBeenStored{false};
double mCursorPositionStored; double mCursorPositionStored;
public:
void OnSelectionSave(const CommandContext &context ); void OnSelectionSave(const CommandContext &context );
void OnSelectionRestore(const CommandContext &context ); void OnSelectionRestore(const CommandContext &context );
void OnCursorPositionStore(const CommandContext &context ); void OnCursorPositionStore(const CommandContext &context );
@ -447,20 +469,23 @@ void OnCursorSelEnd(const CommandContext &context );
int index2{}; int index2{};
bool clipStart2{}; bool clipStart2{};
}; };
FoundClipBoundary FindNextClipBoundary(const WaveTrack* wt, double time); static FoundClipBoundary FindNextClipBoundary(const WaveTrack* wt, double time);
FoundClipBoundary FindPrevClipBoundary(const WaveTrack* wt, double time); static FoundClipBoundary FindPrevClipBoundary(const WaveTrack* wt, double time);
double AdjustForFindingStartTimes(const std::vector<const WaveClip*>& clips, double time); static double AdjustForFindingStartTimes
double AdjustForFindingEndTimes(const std::vector<const WaveClip*>& clips, double time); (const std::vector<const WaveClip*>& clips, double time);
int FindClipBoundaries(double time, bool next, std::vector<FoundClipBoundary>& results); static double AdjustForFindingEndTimes
(const std::vector<const WaveClip*>& clips, double time);
int FindClipBoundaries(AudacityProject &project,
double time, bool next, std::vector<FoundClipBoundary>& results);
void OnCursorNextClipBoundary(const CommandContext &context ); void OnCursorNextClipBoundary(const CommandContext &context );
void OnCursorPrevClipBoundary(const CommandContext &context ); void OnCursorPrevClipBoundary(const CommandContext &context );
void OnCursorClipBoundary(bool next); void OnCursorClipBoundary(AudacityProject &project, bool next);
static wxString ClipBoundaryMessage(const std::vector<FoundClipBoundary>& results); static wxString ClipBoundaryMessage(const std::vector<FoundClipBoundary>& results);
void OnAlignNoSync(const CommandContext &context ); void OnAlignNoSync(const CommandContext &context );
void OnAlign(const CommandContext &context ); void OnAlign(const CommandContext &context );
//void OnAlignMoveSel(int index); //void OnAlignMoveSel(int index);
void HandleAlign(int index, bool moveSel); void HandleAlign(AudacityProject &project, int index, bool moveSel);
size_t mAlignLabelsCount; size_t mAlignLabelsCount;
#ifdef EXPERIMENTAL_SCOREALIGN #ifdef EXPERIMENTAL_SCOREALIGN
@ -478,15 +503,16 @@ void OnMoveSelectionWithTracks(const CommandContext &context );
void OnSyncLock(const CommandContext &context ); void OnSyncLock(const CommandContext &context );
void OnAddLabel(const CommandContext &context ); void OnAddLabel(const CommandContext &context );
void OnAddLabelPlaying(const CommandContext &context ); void OnAddLabelPlaying(const CommandContext &context );
void DoEditLabels(LabelTrack *lt = nullptr, int index = -1); void DoEditLabels(AudacityProject &project,
LabelTrack *lt = nullptr, int index = -1);
void OnEditLabels(const CommandContext &context ); void OnEditLabels(const CommandContext &context );
void OnToggleTypeToCreateLabel(const CommandContext &context ); void OnToggleTypeToCreateLabel(const CommandContext &context );
// Effect Menu // Effect Menu
class OnEffectFlags struct OnEffectFlags
{ {
public:
// No flags specified // No flags specified
static const int kNone = 0x00; static const int kNone = 0x00;
// Flag used to disable prompting for configuration parameteres. // Flag used to disable prompting for configuration parameteres.
@ -506,7 +532,7 @@ void OnApplyMacrosPalette(const CommandContext &context );
void OnManageMacros(const CommandContext &context ); void OnManageMacros(const CommandContext &context );
void OnStereoToMono(const CommandContext &context ); void OnStereoToMono(const CommandContext &context );
void OnAudacityCommand(const CommandContext &context ); void OnAudacityCommand(const CommandContext &context );
void OnManagePluginsMenu(EffectType Type); void OnManagePluginsMenu(AudacityProject &project, EffectType Type);
static void RebuildAllMenuBars(); static void RebuildAllMenuBars();
void OnManageGenerators(const CommandContext &context ); void OnManageGenerators(const CommandContext &context );
void OnManageEffects(const CommandContext &context ); void OnManageEffects(const CommandContext &context );
@ -521,7 +547,7 @@ void OnAbout(const CommandContext &context );
void OnQuickHelp(const CommandContext &context ); void OnQuickHelp(const CommandContext &context );
void OnManual(const CommandContext &context ); void OnManual(const CommandContext &context );
void OnCheckForUpdates(const CommandContext &context ); void OnCheckForUpdates(const CommandContext &context );
void MayCheckForUpdates(); void MayCheckForUpdates(AudacityProject &project);
void OnShowLog(const CommandContext &context ); void OnShowLog(const CommandContext &context );
void OnHelpWelcome(const CommandContext &context ); void OnHelpWelcome(const CommandContext &context );
void OnBenchmark(const CommandContext &context ); void OnBenchmark(const CommandContext &context );
@ -542,7 +568,7 @@ void OnSeparator(const CommandContext &context );
// Keyboard navigation // Keyboard navigation
void NextOrPrevFrame(bool next); void NextOrPrevFrame(AudacityProject &project, bool next);
void PrevFrame(const CommandContext &context ); void PrevFrame(const CommandContext &context );
void NextFrame(const CommandContext &context ); void NextFrame(const CommandContext &context );
@ -569,29 +595,47 @@ enum TimeUnit {
}; };
bool OnlyHandleKeyUp( const CommandContext &context ); bool OnlyHandleKeyUp( const CommandContext &context );
void OnCursorMove(double seekStep); void OnCursorMove(const CommandContext &context, double seekStep);
void OnBoundaryMove(int step); void OnBoundaryMove(const CommandContext &context, int step);
// Handle small cursor and play head movements // Handle small cursor and play head movements
void SeekLeftOrRight void SeekLeftOrRight
(double direction, SelectionOperation operation); (const CommandContext &context, double direction, SelectionOperation operation);
void SeekWhenAudioActive(double seekStep); void SeekWhenAudioActive(double seekStep);
void SeekWhenAudioInactive void SeekWhenAudioInactive
(double seekStep, TimeUnit timeUnit, (const CommandContext &context, double seekStep, TimeUnit timeUnit,
SelectionOperation operation); SelectionOperation operation);
void MoveWhenAudioInactive void MoveWhenAudioInactive
(double seekStep, TimeUnit timeUnit); (const CommandContext &context, double seekStep, TimeUnit timeUnit);
double OffsetTime(double t, double offset, TimeUnit timeUnit, int snapToTime); double OffsetTime(const CommandContext &context,
double t, double offset, TimeUnit timeUnit, int snapToTime);
// Helper for moving by keyboard with snap-to-grid enabled // Helper for moving by keyboard with snap-to-grid enabled
double GridMove(double t, int minPix); double GridMove(AudacityProject &project, double t, int minPix);
// Make sure we return to "public" for subsequent declarations in Project.h. // Last effect applied to this project
public: PluginID mLastEffect{};
// Recent files
wxMenu *mRecentFilesMenu;
CommandFlag mLastFlags;
// 0 is grey out, 1 is Autoselect, 2 is Give warnings.
int mWhatIfNoSelection;
bool mStopIfWasPaused;
bool mCircularTrackNavigation{};
double mSeekShort;
double mSeekLong;
wxLongLong mLastSelectionAdjustment;
#endif #endif

View File

@ -12,6 +12,7 @@
#include "Audacity.h" #include "Audacity.h"
#include "AudacityApp.h" #include "AudacityApp.h"
#include "Project.h" #include "Project.h"
#include "commands/CommandContext.h"
#undef USE_COCOA #undef USE_COCOA
@ -23,7 +24,7 @@
#include <objc/objc.h> #include <objc/objc.h>
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
void AudacityProject::DoMacMinimize(AudacityProject *project) void MenuCommandHandler::DoMacMinimize(AudacityProject *project)
{ {
auto window = project; auto window = project;
if (window) { if (window) {
@ -41,25 +42,25 @@ void AudacityProject::DoMacMinimize(AudacityProject *project)
#endif #endif
// So that the Minimize menu command disables // So that the Minimize menu command disables
project->UpdateMenus(); GetMenuCommandHandler(*project).UpdateMenus(*project);
} }
} }
void AudacityProject::OnMacMinimize(const CommandContext &) void MenuCommandHandler::OnMacMinimize(const CommandContext &context)
{ {
DoMacMinimize(this); DoMacMinimize(&context.project);
} }
void AudacityProject::OnMacMinimizeAll(const CommandContext &) void MenuCommandHandler::OnMacMinimizeAll(const CommandContext &)
{ {
for (const auto project : gAudacityProjects) { for (const auto project : gAudacityProjects) {
DoMacMinimize(project.get()); DoMacMinimize(project.get());
} }
} }
void AudacityProject::OnMacZoom(const CommandContext &) void MenuCommandHandler::OnMacZoom(const CommandContext &context)
{ {
auto window = this; auto window = &context.project;
auto topWindow = static_cast<wxTopLevelWindow*>(window); auto topWindow = static_cast<wxTopLevelWindow*>(window);
auto maximized = topWindow->IsMaximized(); auto maximized = topWindow->IsMaximized();
if (window) { if (window) {
@ -77,7 +78,7 @@ void AudacityProject::OnMacZoom(const CommandContext &)
} }
} }
void AudacityProject::OnMacBringAllToFront(const CommandContext &) void MenuCommandHandler::OnMacBringAllToFront(const CommandContext &)
{ {
// Reall this de-miniaturizes all, which is not exactly the standard // Reall this de-miniaturizes all, which is not exactly the standard
// behavior. // behavior.

View File

@ -685,8 +685,8 @@ wxColour MixerTrackCluster::GetTrackColor()
void MixerTrackCluster::HandleSelect(bool bShiftDown, bool bControlDown) void MixerTrackCluster::HandleSelect(bool bShiftDown, bool bControlDown)
{ {
mProject->HandleListSelection( mTrack.get(), bShiftDown, bControlDown, true GetMenuCommandHandler(*mProject).HandleListSelection(*mProject,
); mTrack.get(), bShiftDown, bControlDown, true);
} }
void MixerTrackCluster::OnMouseEvent(wxMouseEvent& event) void MixerTrackCluster::OnMouseEvent(wxMouseEvent& event)

View File

@ -95,6 +95,7 @@ scroll information. It also has some status flags.
#include "AudacityApp.h" #include "AudacityApp.h"
#include "AColor.h" #include "AColor.h"
#include "AudioIO.h" #include "AudioIO.h"
#include "BatchProcessDialog.h"
#include "Dependencies.h" #include "Dependencies.h"
#include "Diags.h" #include "Diags.h"
#include "HistoryWindow.h" #include "HistoryWindow.h"
@ -105,6 +106,7 @@ scroll information. It also has some status flags.
#include "import/Import.h" #include "import/Import.h"
#include "LabelTrack.h" #include "LabelTrack.h"
#include "Legacy.h" #include "Legacy.h"
#include "LyricsWindow.h"
#include "Mix.h" #include "Mix.h"
#include "NoteTrack.h" #include "NoteTrack.h"
#include "Prefs.h" #include "Prefs.h"
@ -469,7 +471,7 @@ public:
for (const auto &name : sortednames) { for (const auto &name : sortednames) {
#ifdef USE_MIDI #ifdef USE_MIDI
if (Importer::IsMidi(name)) if (Importer::IsMidi(name))
AudacityProject::DoImportMIDI(mProject, name); MenuCommandHandler::DoImportMIDI(mProject, name);
else else
#endif #endif
mProject->Import(name); mProject->Import(name);
@ -978,6 +980,8 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
// Initialize view info (shared with TrackPanel) // Initialize view info (shared with TrackPanel)
// //
mMenuCommandHandler = std::make_unique<MenuCommandHandler>();
UpdatePrefs(); UpdatePrefs();
mLockPlayRegion = false; mLockPlayRegion = false;
@ -1137,7 +1141,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
mTrackPanel->AddOverlay(mScrubOverlay.get()); mTrackPanel->AddOverlay(mScrubOverlay.get());
#endif #endif
CreateMenusAndCommands(); mMenuCommandHandler->CreateMenusAndCommands(*this);
mTrackPanel->SetBackgroundCell(mBackgroundCell); mTrackPanel->SetBackgroundCell(mBackgroundCell);
@ -1262,12 +1266,9 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
&AudacityProject::OnCapture, &AudacityProject::OnCapture,
this); this);
//Initialize the last selection adjustment time.
mLastSelectionAdjustment = ::wxGetLocalTimeMillis();
#ifdef EXPERIMENTAL_DA2 #ifdef EXPERIMENTAL_DA2
ClearBackground();// For wxGTK. ClearBackground();// For wxGTK.
#endif #endif
mLastF0 = mLastF1 = SelectedRegion::UndefinedFrequency;
} }
AudacityProject::~AudacityProject() AudacityProject::~AudacityProject()
@ -1276,11 +1277,6 @@ AudacityProject::~AudacityProject()
if(HasCapture()) if(HasCapture())
ReleaseMouse(); ReleaseMouse();
if (wxGetApp().GetRecentFiles())
{
wxGetApp().GetRecentFiles()->RemoveMenu(mRecentFilesMenu);
}
if(mTrackPanel) { if(mTrackPanel) {
#ifdef EXPERIMENTAL_SCRUBBING_BASIC #ifdef EXPERIMENTAL_SCRUBBING_BASIC
mTrackPanel->RemoveOverlay(mScrubOverlay.get()); mTrackPanel->RemoveOverlay(mScrubOverlay.get());
@ -1332,17 +1328,6 @@ void AudacityProject::UpdatePrefsVariables()
#else #else
gPrefs->Read(wxT("/GUI/Help"), &mHelpPref, wxT("Local") ); gPrefs->Read(wxT("/GUI/Help"), &mHelpPref, wxT("Local") );
#endif #endif
bool bSelectAllIfNone;
gPrefs->Read(wxT("/GUI/SelectAllOnNone"), &bSelectAllIfNone, false);
// 0 is grey out, 1 is Autoselect, 2 is Give warnings.
#ifdef EXPERIMENTAL_DA
// DA warns or greys out.
mWhatIfNoSelection = bSelectAllIfNone ? 2 : 0;
#else
// Audacity autoselects or warns.
mWhatIfNoSelection = bSelectAllIfNone ? 1 : 2;
#endif
mStopIfWasPaused = true; // not configurable for now, but could be later.
gPrefs->Read(wxT("/GUI/ShowSplashScreen"), &mShowSplashScreen, true); gPrefs->Read(wxT("/GUI/ShowSplashScreen"), &mShowSplashScreen, true);
gPrefs->Read(wxT("/GUI/Solo"), &mSoloPref, wxT("Simple")); gPrefs->Read(wxT("/GUI/Solo"), &mSoloPref, wxT("Simple"));
// Update the old default to the NEW default. // Update the old default to the NEW default.
@ -1368,9 +1353,6 @@ void AudacityProject::UpdatePrefsVariables()
#endif #endif
mDefaultFormat = QualityPrefs::SampleFormatChoice(); mDefaultFormat = QualityPrefs::SampleFormatChoice();
gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &mSeekShort, 1.0);
gPrefs->Read(wxT("/AudioIO/SeekLongPeriod"), &mSeekLong, 15.0);
} }
void AudacityProject::UpdatePrefs() void AudacityProject::UpdatePrefs()
@ -1379,8 +1361,7 @@ void AudacityProject::UpdatePrefs()
SetProjectTitle(); SetProjectTitle();
gPrefs->Read(wxT("/GUI/CircularTrackNavigation"), &mCircularTrackNavigation, GetMenuCommandHandler(*this).UpdatePrefs();
false);
if (mTrackPanel) { if (mTrackPanel) {
mTrackPanel->UpdatePrefs(); mTrackPanel->UpdatePrefs();
@ -1494,6 +1475,11 @@ const Tags *AudacityProject::GetTags()
return mTags.get(); return mTags.get();
} }
void AudacityProject::SetTags( const std::shared_ptr<Tags> &tags )
{
mTags = tags;
}
wxString AudacityProject::GetName() wxString AudacityProject::GetName()
{ {
wxString name = wxFileNameFromPath(mFileName); wxString name = wxFileNameFromPath(mFileName);
@ -2073,7 +2059,7 @@ void AudacityProject::FixScrollbars()
mTrackPanel->Refresh(false); mTrackPanel->Refresh(false);
} }
UpdateMenus(); GetMenuCommandHandler(*this).UpdateMenus(*this);
if (oldhstate != newhstate || oldvstate != newvstate) { if (oldhstate != newhstate || oldvstate != newvstate) {
UpdateLayout(); UpdateLayout();
@ -2320,13 +2306,14 @@ void AudacityProject::DoScroll()
GetTrackPanel()->HandleCursorForPresentMouseState(); } ); GetTrackPanel()->HandleCursorForPresentMouseState(); } );
} }
bool AudacityProject::ReportIfActionNotAllowed bool MenuCommandHandler::ReportIfActionNotAllowed
( const wxString & Name, CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask ) ( AudacityProject &project,
const wxString & Name, CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask )
{ {
bool bAllowed = TryToMakeActionAllowed( flags, flagsRqd, mask ); bool bAllowed = TryToMakeActionAllowed( project, flags, flagsRqd, mask );
if( bAllowed ) if( bAllowed )
return true; return true;
CommandManager* cm = GetCommandManager(); CommandManager* cm = project.GetCommandManager();
if (!cm) return false; if (!cm) return false;
cm->TellUserWhyDisallowed( Name, flags & mask, flagsRqd & mask); cm->TellUserWhyDisallowed( Name, flags & mask, flagsRqd & mask);
return false; return false;
@ -2336,13 +2323,14 @@ bool AudacityProject::ReportIfActionNotAllowed
/// Determines if flags for command are compatible with current state. /// Determines if flags for command are compatible with current state.
/// If not, then try some recovery action to make it so. /// If not, then try some recovery action to make it so.
/// @return whether compatible or not after any actions taken. /// @return whether compatible or not after any actions taken.
bool AudacityProject::TryToMakeActionAllowed bool MenuCommandHandler::TryToMakeActionAllowed
( CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask ) ( AudacityProject &project,
CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask )
{ {
bool bAllowed; bool bAllowed;
if( !flags ) if( !flags )
flags = GetUpdateFlags(); flags = GetUpdateFlags(project);
bAllowed = ((flags & mask) == (flagsRqd & mask)); bAllowed = ((flags & mask) == (flagsRqd & mask));
if( bAllowed ) if( bAllowed )
@ -2353,9 +2341,9 @@ bool AudacityProject::TryToMakeActionAllowed
auto MissingFlags = (~flags & flagsRqd) & mask; auto MissingFlags = (~flags & flagsRqd) & mask;
if( mStopIfWasPaused && (MissingFlags & AudioIONotBusyFlag ) ){ if( mStopIfWasPaused && (MissingFlags & AudioIONotBusyFlag ) ){
StopIfPaused(); project.StopIfPaused();
// Hope this will now reflect stopped audio. // Hope this will now reflect stopped audio.
flags = GetUpdateFlags(); flags = GetUpdateFlags(project);
bAllowed = ((flags & mask) == (flagsRqd & mask)); bAllowed = ((flags & mask) == (flagsRqd & mask));
if( bAllowed ) if( bAllowed )
return true; return true;
@ -2384,8 +2372,8 @@ bool AudacityProject::TryToMakeActionAllowed
// This was 'OnSelectAll'. Changing it to OnSelectSomething means if // This was 'OnSelectAll'. Changing it to OnSelectSomething means if
// selecting all tracks is enough, we just do that. // selecting all tracks is enough, we just do that.
OnSelectSomething(*this); GetMenuCommandHandler(project).OnSelectSomething(project);
flags = GetUpdateFlags(); flags = GetUpdateFlags(project);
bAllowed = ((flags & mask) == (flagsRqd & mask)); bAllowed = ((flags & mask) == (flagsRqd & mask));
return bAllowed; return bAllowed;
} }
@ -2405,9 +2393,9 @@ void AudacityProject::OnMenu(wxCommandEvent & event)
return; return;
} }
#endif #endif
bool handled = mCommandManager.HandleMenuID(event.GetId(), bool handled = mCommandManager.HandleMenuID(
GetUpdateFlags(), event.GetId(), GetMenuCommandHandler(*this).GetUpdateFlags(*this),
NoFlagsSpecifed); NoFlagsSpecifed);
if (handled) if (handled)
event.Skip(false); event.Skip(false);
@ -2419,7 +2407,7 @@ void AudacityProject::OnMenu(wxCommandEvent & event)
void AudacityProject::OnUpdateUI(wxUpdateUIEvent & WXUNUSED(event)) void AudacityProject::OnUpdateUI(wxUpdateUIEvent & WXUNUSED(event))
{ {
UpdateMenus(); GetMenuCommandHandler(*this).UpdateMenus(*this);
} }
void AudacityProject::MacShowUndockedToolbars(bool show) void AudacityProject::MacShowUndockedToolbars(bool show)
@ -3102,7 +3090,7 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
#ifdef EXPERIMENTAL_DRAG_DROP_PLUG_INS #ifdef EXPERIMENTAL_DRAG_DROP_PLUG_INS
// Is it a plug-in? // Is it a plug-in?
if (PluginManager::Get().DropFile(fileName)) { if (PluginManager::Get().DropFile(fileName)) {
RebuildAllMenuBars(); MenuCommandHandler::RebuildAllMenuBars();
} }
else else
// No, so import. // No, so import.
@ -3111,7 +3099,7 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
{ {
#ifdef USE_MIDI #ifdef USE_MIDI
if (Importer::IsMidi(fileName)) if (Importer::IsMidi(fileName))
DoImportMIDI(this, fileName); MenuCommandHandler::DoImportMIDI(this, fileName);
else else
#endif #endif
Import(fileName); Import(fileName);
@ -3317,7 +3305,7 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
mTrackPanel->Refresh(true); mTrackPanel->Refresh(true);
*/ */
closed = true; closed = true;
this->OnClose(*this); GetMenuCommandHandler(*this).OnClose(*this);
return; return;
} }
else if (status & FSCKstatus_CHANGED) else if (status & FSCKstatus_CHANGED)
@ -4398,7 +4386,7 @@ AudacityProject::AddImportedTracks(const wxString &fileName,
void AudacityProject::ZoomAfterImport(Track *pTrack) void AudacityProject::ZoomAfterImport(Track *pTrack)
{ {
OnZoomFit(*this); GetMenuCommandHandler(*this).OnZoomFit(*this);
mTrackPanel->SetFocus(); mTrackPanel->SetFocus();
RedrawProject(); RedrawProject();
@ -4467,9 +4455,10 @@ bool AudacityProject::Import(const wxString &fileName, WaveTrackArray* pTrackArr
SelectNone(); SelectNone();
SelectAllIfNone(); SelectAllIfNone();
const CommandContext context( *this); const CommandContext context( *this);
DoEffect(EffectManager::Get().GetEffectByIdentifier(wxT("Normalize")), GetMenuCommandHandler(*this)
.DoEffect(EffectManager::Get().GetEffectByIdentifier(wxT("Normalize")),
context, context,
OnEffectFlags::kConfigured); MenuCommandHandler::OnEffectFlags::kConfigured);
} }
// This is a no-fail: // This is a no-fail:
@ -4716,9 +4705,9 @@ void AudacityProject::InitialState()
if (mHistoryWindow) if (mHistoryWindow)
mHistoryWindow->UpdateDisplay(); mHistoryWindow->UpdateDisplay();
ModifyUndoMenuItems(); GetMenuCommandHandler(*this).ModifyUndoMenuItems(*this);
UpdateMenus(); GetMenuCommandHandler(*this).UpdateMenus(*this);
this->UpdateLyrics(); this->UpdateLyrics();
this->UpdateMixerBoard(); this->UpdateMixerBoard();
} }
@ -4754,9 +4743,9 @@ void AudacityProject::PushState(const wxString &desc,
if (mHistoryWindow) if (mHistoryWindow)
mHistoryWindow->UpdateDisplay(); mHistoryWindow->UpdateDisplay();
ModifyUndoMenuItems(); GetMenuCommandHandler(*this).ModifyUndoMenuItems(*this);
UpdateMenus(); GetMenuCommandHandler(*this).UpdateMenus(*this);
// Some state pushes, like changing a track gain control (& probably others), // Some state pushes, like changing a track gain control (& probably others),
// should not repopulate Lyrics Window and MixerBoard. // should not repopulate Lyrics Window and MixerBoard.
@ -4770,7 +4759,7 @@ void AudacityProject::PushState(const wxString &desc,
} }
if (GetTracksFitVerticallyZoomed()) if (GetTracksFitVerticallyZoomed())
this->DoZoomFitV(); GetMenuCommandHandler(*this).DoZoomFitV(*this);
if((flags & UndoPush::AUTOSAVE) != UndoPush::MINIMAL) if((flags & UndoPush::AUTOSAVE) != UndoPush::MINIMAL)
AutoSave(); AutoSave();
@ -4842,7 +4831,7 @@ void AudacityProject::PopState(const UndoState &state)
HandleResize(); HandleResize();
UpdateMenus(); GetMenuCommandHandler(*this).UpdateMenus(*this);
this->UpdateLyrics(); this->UpdateLyrics();
this->UpdateMixerBoard(); this->UpdateMixerBoard();
@ -4858,7 +4847,7 @@ void AudacityProject::SetStateTo(unsigned int n)
HandleResize(); HandleResize();
mTrackPanel->SetFocusedTrack(NULL); mTrackPanel->SetFocusedTrack(NULL);
mTrackPanel->Refresh(false); mTrackPanel->Refresh(false);
ModifyUndoMenuItems(); GetMenuCommandHandler(*this).ModifyUndoMenuItems(*this);
this->UpdateLyrics(); this->UpdateLyrics();
this->UpdateMixerBoard(); this->UpdateMixerBoard();
} }
@ -5359,7 +5348,7 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action )
auto dest = ( wt->*action )( region.start, region.end ); auto dest = ( wt->*action )( region.start, region.end );
if( dest ) if( dest )
{ {
FinishCopy( wt, dest.get() ); MenuCommandHandler::FinishCopy( wt, dest.get() );
if( !merged ) if( !merged )
merged = std::move(dest); merged = std::move(dest);
else else
@ -5663,8 +5652,8 @@ You are saving directly to a slow external storage device\n\
// Reset timer record // Reset timer record
if (IsTimerRecordCancelled()) if (IsTimerRecordCancelled())
{ {
OnUndo(*this); GetMenuCommandHandler(*this).OnUndo(*this);
ResetTimerRecordFlag(); ResetTimerRecordCancelled();
} }
// Refresh the project window // Refresh the project window
@ -6053,8 +6042,8 @@ bool AudacityProject::IsProjectSaved() {
// This is done to empty out the tracks, but without creating a new project. // This is done to empty out the tracks, but without creating a new project.
void AudacityProject::ResetProjectToEmpty() { void AudacityProject::ResetProjectToEmpty() {
OnSelectAll(*this); GetMenuCommandHandler(*this).OnSelectAll(*this);
OnRemoveTracks(*this); GetMenuCommandHandler(*this).OnRemoveTracks(*this);
// A new DirManager. // A new DirManager.
mDirManager = std::make_shared<DirManager>(); mDirManager = std::make_shared<DirManager>();
mTrackFactory.reset(safenew TrackFactory{ mDirManager, &mViewInfo }); mTrackFactory.reset(safenew TrackFactory{ mDirManager, &mViewInfo });
@ -6351,3 +6340,61 @@ bool AudacityProject::IsFocused( const wxWindow *window ) const
{ {
return window == mFocusLender || window == wxWindow::FindFocus(); return window == mFocusLender || window == wxWindow::FindFocus();
} }
LyricsWindow* AudacityProject::GetLyricsWindow(bool create)
{
if (create && !mLyricsWindow)
mLyricsWindow = safenew LyricsWindow{ this };
return mLyricsWindow;
}
MixerBoardFrame* AudacityProject::GetMixerBoardFrame(bool create)
{
if (create && !mMixerBoardFrame) {
mMixerBoardFrame = safenew MixerBoardFrame{ this };
mMixerBoard = mMixerBoardFrame->mMixerBoard;
}
return mMixerBoardFrame;
}
HistoryWindow *AudacityProject::GetHistoryWindow(bool create)
{
if (create && !mHistoryWindow)
mHistoryWindow = safenew HistoryWindow{ this, GetUndoManager() };
return mHistoryWindow;
}
MacrosWindow *AudacityProject::GetMacrosWindow(bool bExpanded, bool create)
{
if (create && !mMacrosWindow)
mMacrosWindow = safenew MacrosWindow{ this, bExpanded };
if (mMacrosWindow) {
mMacrosWindow->Show();
mMacrosWindow->Raise();
mMacrosWindow->UpdateDisplay( bExpanded );
}
return mMacrosWindow;
}
FreqWindow *AudacityProject::GetFreqWindow(bool create)
{
if (create && !mFreqWindow)
mFreqWindow.reset( safenew FreqWindow{
this, -1, _("Frequency Analysis"),
wxPoint{ 150, 150 }
} );
return mFreqWindow.get();
}
ContrastDialog *AudacityProject::GetContrastDialog(bool create)
{
// All of this goes away when the Contrast Dialog is converted to a module
if(create && !mContrastDialog)
mContrastDialog.reset( safenew ContrastDialog{
this, -1, _("Contrast Analysis (WCAG 2 compliance)"),
wxPoint{ 150, 150 }
} );
return mContrastDialog.get();
}

View File

@ -172,6 +172,15 @@ class WaveTrack;
#include "./commands/CommandManager.h" #include "./commands/CommandManager.h"
struct MenuCommandHandler : public wxEvtHandler {
MenuCommandHandler();
~MenuCommandHandler();
#include "Menus.h"
};
MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project);
class AUDACITY_DLL_API AudacityProject final : public wxFrame, class AUDACITY_DLL_API AudacityProject final : public wxFrame,
public TrackPanelListener, public TrackPanelListener,
@ -212,6 +221,7 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
void GetPlayRegion(double* playRegionStart, double *playRegionEnd); void GetPlayRegion(double* playRegionStart, double *playRegionEnd);
bool IsPlayRegionLocked() { return mLockPlayRegion; } bool IsPlayRegionLocked() { return mLockPlayRegion; }
void SetPlayRegionLocked(bool value) { mLockPlayRegion = value; }
void SetSel0(double); //Added by STM void SetSel0(double); //Added by STM
void SetSel1(double); //Added by STM void SetSel1(double); //Added by STM
@ -223,6 +233,7 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
TrackFactory *GetTrackFactory(); TrackFactory *GetTrackFactory();
AdornedRulerPanel *GetRulerPanel(); AdornedRulerPanel *GetRulerPanel();
const Tags *GetTags(); const Tags *GetTags();
void SetTags( const std::shared_ptr<Tags> &tags );
int GetAudioIOToken() const; int GetAudioIOToken() const;
bool IsAudioActive() const; bool IsAudioActive() const;
void SetAudioIOToken(int token); void SetAudioIOToken(int token);
@ -276,6 +287,8 @@ private:
void EnqueueODTasks(); void EnqueueODTasks();
public: public:
using wxFrame::DetachMenuBar;
bool WarnOfLegacyFile( ); bool WarnOfLegacyFile( );
// If pNewTrackList is passed in non-NULL, it gets filled with the pointers to NEW tracks. // If pNewTrackList is passed in non-NULL, it gets filled with the pointers to NEW tracks.
@ -332,7 +345,7 @@ public:
// Timer Record Auto Save/Export Routines // Timer Record Auto Save/Export Routines
bool SaveFromTimerRecording(wxFileName fnFile); bool SaveFromTimerRecording(wxFileName fnFile);
bool ExportFromTimerRecording(wxFileName fnFile, int iFormat, int iSubFormat, int iFilterIndex); bool ExportFromTimerRecording(wxFileName fnFile, int iFormat, int iSubFormat, int iFilterIndex);
int GetOpenProjectCount(); static int GetOpenProjectCount();
bool IsProjectSaved(); bool IsProjectSaved();
void ResetProjectToEmpty(); void ResetProjectToEmpty();
@ -343,8 +356,6 @@ public:
// Converts number of minutes to human readable format // Converts number of minutes to human readable format
wxString GetHoursMinsString(int iMinutes); wxString GetHoursMinsString(int iMinutes);
#include "Menus.h"
CommandManager *GetCommandManager() { return &mCommandManager; } CommandManager *GetCommandManager() { return &mCommandManager; }
const CommandManager *GetCommandManager() const { return &mCommandManager; } const CommandManager *GetCommandManager() const { return &mCommandManager; }
@ -354,7 +365,6 @@ public:
static void CaptureKeyboard(wxWindow *handler); static void CaptureKeyboard(wxWindow *handler);
static void ReleaseKeyboard(wxWindow *handler); static void ReleaseKeyboard(wxWindow *handler);
void RebuildMenuBar();
void RebuildOtherMenus(); void RebuildOtherMenus();
void MayStartMonitoring(); void MayStartMonitoring();
@ -395,9 +405,6 @@ public:
int GetProjectNumber(){ return mProjectNo;}; int GetProjectNumber(){ return mProjectNo;};
static int CountUnnamed(); static int CountUnnamed();
static void RefreshAllTitles(bool bShowProjectNumbers ); static void RefreshAllTitles(bool bShowProjectNumbers );
// checkActive is a temporary hack that should be removed as soon as we
// get multiple effect preview working
void UpdateMenus(bool checkActive = true);
void UpdatePrefs(); void UpdatePrefs();
void UpdatePrefsVariables(); void UpdatePrefsVariables();
void RedrawProject(const bool bForceWaveTracks = false); void RedrawProject(const bool bForceWaveTracks = false);
@ -514,8 +521,13 @@ public:
MeterPanel *GetCaptureMeter(); MeterPanel *GetCaptureMeter();
void SetCaptureMeter(MeterPanel *capture); void SetCaptureMeter(MeterPanel *capture);
LyricsWindow* GetLyricsWindow() { return mLyricsWindow; } LyricsWindow* GetLyricsWindow(bool create = false);
MixerBoardFrame* GetMixerBoardFrame(bool create = false);
MixerBoard* GetMixerBoard() { return mMixerBoard; } MixerBoard* GetMixerBoard() { return mMixerBoard; }
HistoryWindow *GetHistoryWindow(bool create = false);
MacrosWindow *GetMacrosWindow(bool bExpanded, bool create = false);
FreqWindow *GetFreqWindow(bool create = false);
ContrastDialog *GetContrastDialog(bool create = false);
wxStatusBar* GetStatusBar() { return mStatusBar; } wxStatusBar* GetStatusBar() { return mStatusBar; }
@ -565,12 +577,6 @@ public:
void OnAudioIOStopRecording() override; void OnAudioIOStopRecording() override;
void OnAudioIONewBlockFiles(const AutoSaveFile & blockFileLog) override; void OnAudioIONewBlockFiles(const AutoSaveFile & blockFileLog) override;
// Command Handling
bool ReportIfActionNotAllowed
( const wxString & Name, CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask );
bool TryToMakeActionAllowed
( CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask );
bool UndoAvailable(); bool UndoAvailable();
bool RedoAvailable(); bool RedoAvailable();
@ -589,7 +595,6 @@ public:
// a crash, as it can take many seconds for large (eg. 10 track-hours) projects // a crash, as it can take many seconds for large (eg. 10 track-hours) projects
void RecreateMixerBoard(); void RecreateMixerBoard();
private:
void PopState(const UndoState &state); void PopState(const UndoState &state);
void UpdateLyrics(); void UpdateLyrics();
@ -600,11 +605,12 @@ public:
void AutoSave(); void AutoSave();
void DeleteCurrentAutoSaveFile(); void DeleteCurrentAutoSaveFile();
public:
double GetZoomOfToFit(); double GetZoomOfToFit();
double GetZoomOfSelection(); double GetZoomOfSelection();
double GetZoomOfPreset(int preset ); double GetZoomOfPreset(int preset );
public:
bool IsSoloSimple() const { return mSoloPref == wxT("Simple"); } bool IsSoloSimple() const { return mSoloPref == wxT("Simple"); }
bool IsSoloNone() const { return mSoloPref == wxT("None"); } bool IsSoloNone() const { return mSoloPref == wxT("None"); }
@ -621,9 +627,6 @@ public:
double mRate; double mRate;
sampleFormat mDefaultFormat; sampleFormat mDefaultFormat;
// Recent files
wxMenu *mRecentFilesMenu;
// Tags (artist name, song properties, MP3 ID3 info, etc.) // Tags (artist name, song properties, MP3 ID3 info, etc.)
// The structure may be shared with undo history entries // The structure may be shared with undo history entries
// To keep undo working correctly, always replace this with a NEW duplicate // To keep undo working correctly, always replace this with a NEW duplicate
@ -640,13 +643,14 @@ public:
std::shared_ptr<TrackList> mLastSavedTracks; std::shared_ptr<TrackList> mLastSavedTracks;
public:
// Clipboard (static because it is shared by all projects) // Clipboard (static because it is shared by all projects)
static std::shared_ptr<TrackList> msClipboard; static std::shared_ptr<TrackList> msClipboard;
static AudacityProject *msClipProject; static AudacityProject *msClipProject;
static double msClipT0; static double msClipT0;
static double msClipT1; static double msClipT1;
public:
///Prevents DELETE from external thread - for e.g. use of GetActiveProject ///Prevents DELETE from external thread - for e.g. use of GetActiveProject
//shared by all projects //shared by all projects
static ODLock &AllProjectDeleteMutex(); static ODLock &AllProjectDeleteMutex();
@ -660,8 +664,6 @@ private:
CommandManager mCommandManager; CommandManager mCommandManager;
CommandFlag mLastFlags;
// Window elements // Window elements
wxString mLastMainStatusMessage; wxString mLastMainStatusMessage;
@ -674,11 +676,15 @@ private:
wxPanel *mTopPanel{}; wxPanel *mTopPanel{};
TrackPanel *mTrackPanel{}; TrackPanel *mTrackPanel{};
SelectionState mSelectionState{}; SelectionState mSelectionState{};
bool mCircularTrackNavigation{};
std::unique_ptr<TrackFactory> mTrackFactory{}; std::unique_ptr<TrackFactory> mTrackFactory{};
wxPanel * mMainPanel; wxPanel * mMainPanel;
wxScrollBar *mHsbar; wxScrollBar *mHsbar;
wxScrollBar *mVsbar; wxScrollBar *mVsbar;
public:
wxScrollBar &GetVerticalScrollBar() { return *mVsbar; }
private:
bool mAutoScrolling{ false }; bool mAutoScrolling{ false };
bool mActive{ true }; bool mActive{ true };
bool mIconized; bool mIconized;
@ -715,8 +721,9 @@ private:
wxRect GetNormalizedWindowState() const { return mNormalizedWindowState; } wxRect GetNormalizedWindowState() const { return mNormalizedWindowState; }
bool IsTimerRecordCancelled(){return mTimerRecordCanceled;} bool IsTimerRecordCancelled(){return mTimerRecordCanceled;}
void ResetTimerRecordFlag(){mTimerRecordCanceled=false;} void SetTimerRecordCancelled(){mTimerRecordCanceled=true;}
private: void ResetTimerRecordCancelled(){mTimerRecordCanceled=false;}
//sort method used by OnSortName and OnSortTime //sort method used by OnSortName and OnSortTime
//currently only supported flags are kAudacitySortByName and kAudacitySortByName //currently only supported flags are kAudacitySortByName and kAudacitySortByName
//in the future we might have 0x01 as sort ascending and we can bit or it //in the future we might have 0x01 as sort ascending and we can bit or it
@ -724,6 +731,7 @@ private:
#define kAudacitySortByName (1 << 2) #define kAudacitySortByName (1 << 2)
void SortTracks(int flags); void SortTracks(int flags);
private:
int mAudioIOToken{ -1 }; int mAudioIOToken{ -1 };
bool mIsDeleting{ false }; bool mIsDeleting{ false };
@ -732,9 +740,9 @@ private:
bool mShowId3Dialog{ true }; //lda bool mShowId3Dialog{ true }; //lda
bool mEmptyCanBeDirty; bool mEmptyCanBeDirty;
// 0 is grey out, 1 is Autoselect, 2 is Give warnings. public:
int mWhatIfNoSelection; bool EmptyCanBeDirty() const { return mEmptyCanBeDirty; }
bool mStopIfWasPaused; private:
bool mIsSyncLocked; bool mIsSyncLocked;
@ -762,9 +770,6 @@ private:
wxArrayString mStrOtherNamesArray; // used to make sure compressed file names are unique wxArrayString mStrOtherNamesArray; // used to make sure compressed file names are unique
// Last effect applied to this project
PluginID mLastEffect{};
wxRect mNormalizedWindowState; wxRect mNormalizedWindowState;
//flag for cancellation of timer record. //flag for cancellation of timer record.
@ -773,19 +778,23 @@ private:
// Are we currently closing as the result of a menu command? // Are we currently closing as the result of a menu command?
bool mMenuClose{ false }; bool mMenuClose{ false };
public:
void SetMenuClose(bool value) { mMenuClose = value; }
private:
bool mbInitializingScrollbar{ false }; bool mbInitializingScrollbar{ false };
// Flag that we're recoding. // Flag that we're recoding.
bool mIsCapturing{ false }; bool mIsCapturing{ false };
public:
bool IsCapturing() const { return mIsCapturing; }
private:
// Keyboard capture // Keyboard capture
wxWindow *mKeyboardCaptureHandler{}; wxWindow *mKeyboardCaptureHandler{};
double mSeekShort;
double mSeekLong;
wxLongLong mLastSelectionAdjustment;
// See explanation in OnCloseWindow // See explanation in OnCloseWindow
bool mIsBeingDeleted{ false }; bool mIsBeingDeleted{ false };
@ -806,6 +815,14 @@ public:
const Scrubber &GetScrubber() const { return *mScrubber; } const Scrubber &GetScrubber() const { return *mScrubber; }
#endif #endif
private:
std::unique_ptr<MenuCommandHandler> mMenuCommandHandler;
public:
friend MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project);
public:
class PlaybackScroller final : public wxEvtHandler class PlaybackScroller final : public wxEvtHandler
{ {
public: public:

View File

@ -527,7 +527,7 @@ int TimerRecordDialog::RunWaitDialog()
return POST_TIMER_RECORD_CANCEL_WAIT; return POST_TIMER_RECORD_CANCEL_WAIT;
} else { } else {
// Record for specified time. // Record for specified time.
pProject->OnRecord(*pProject); GetMenuCommandHandler(*pProject).OnRecord(*pProject);
bool bIsRecording = true; bool bIsRecording = true;
wxString sPostAction = m_pTimerAfterCompleteChoiceCtrl->GetString(m_pTimerAfterCompleteChoiceCtrl->GetSelection()); wxString sPostAction = m_pTimerAfterCompleteChoiceCtrl->GetString(m_pTimerAfterCompleteChoiceCtrl->GetSelection());
@ -579,7 +579,7 @@ int TimerRecordDialog::RunWaitDialog()
// Must do this AFTER the timer project dialog has been deleted to ensure the application // Must do this AFTER the timer project dialog has been deleted to ensure the application
// responds to the AUDIOIO events...see not about bug #334 in the ProgressDialog constructor. // responds to the AUDIOIO events...see not about bug #334 in the ProgressDialog constructor.
pProject->OnStop(*pProject); GetMenuCommandHandler(*pProject).OnStop(*pProject);
// Let the caller handle cancellation or failure from recording progress. // Let the caller handle cancellation or failure from recording progress.
if (updateResult == ProgressResult::Cancelled || updateResult == ProgressResult::Failed) if (updateResult == ProgressResult::Cancelled || updateResult == ProgressResult::Failed)

View File

@ -95,6 +95,9 @@ class AUDACITY_DLL_API UndoManager {
UndoManager(); UndoManager();
~UndoManager(); ~UndoManager();
UndoManager( const UndoManager& ) = delete;
UndoManager& operator = ( const UndoManager& ) = delete;
void PushState(const TrackList * l, void PushState(const TrackList * l,
const SelectedRegion &selectedRegion, const SelectedRegion &selectedRegion,
const std::shared_ptr<Tags> &tags, const std::shared_ptr<Tags> &tags,

View File

@ -185,7 +185,7 @@ bool AudacityCommand::SetAutomationParameters(const wxString & parms)
return TransferDataToWindow(); return TransferDataToWindow();
} }
bool AudacityCommand::DoAudacityCommand(wxWindow *parent, bool AudacityCommand::DoAudacityCommand(wxWindow *parent,
const CommandContext & context, const CommandContext & context,
bool shouldPrompt /* = true */) bool shouldPrompt /* = true */)
{ {

View File

@ -1484,7 +1484,7 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent &
return false; return false;
} }
auto flags = project->GetUpdateFlags(); auto flags = GetMenuCommandHandler(*project).GetUpdateFlags(*project);
wxKeyEvent temp = evt; wxKeyEvent temp = evt;
@ -1578,8 +1578,9 @@ bool CommandManager::HandleCommandEntry(const CommandListEntry * entry,
NiceName.Replace("&", "");// remove & NiceName.Replace("&", "");// remove &
NiceName.Replace(".","");// remove ... NiceName.Replace(".","");// remove ...
// NB: The call may have the side effect of changing flags. // NB: The call may have the side effect of changing flags.
bool allowed = proj->ReportIfActionNotAllowed( bool allowed =
NiceName, flags, entry->flags, combinedMask ); GetMenuCommandHandler(*proj).ReportIfActionNotAllowed( *proj,
NiceName, flags, entry->flags, combinedMask );
// If the function was disallowed, it STILL should count as having been // If the function was disallowed, it STILL should count as having been
// handled (by doing nothing or by telling the user of the problem). // handled (by doing nothing or by telling the user of the problem).
// Otherwise we may get other handlers having a go at obeying the command. // Otherwise we may get other handlers having a go at obeying the command.
@ -1613,7 +1614,7 @@ bool CommandManager::HandleMenuID(int id, CommandFlag flags, CommandMask mask)
factories.push_back(&keyConfigPrefsFactory); factories.push_back(&keyConfigPrefsFactory);
GlobalPrefsDialog dialog(GetActiveProject(), factories); GlobalPrefsDialog dialog(GetActiveProject(), factories);
dialog.ShowModal(); dialog.ShowModal();
AudacityProject::RebuildAllMenuBars(); MenuCommandHandler::RebuildAllMenuBars();
return true; return true;
} }
#endif #endif
@ -1664,7 +1665,7 @@ bool CommandManager::HandleTextualCommand(const wxString & Str, const CommandCon
{ {
if (em.GetCommandIdentifier(plug->GetID()).IsSameAs(Str, false)) if (em.GetCommandIdentifier(plug->GetID()).IsSameAs(Str, false))
{ {
return proj->DoEffect(plug->GetID(), context, AudacityProject::OnEffectFlags::kConfigured); return GetMenuCommandHandler(*proj).DoEffect(plug->GetID(), context, MenuCommandHandler::OnEffectFlags::kConfigured);
} }
plug = pm.GetNextPlugin(PluginTypeEffect); plug = pm.GetNextPlugin(PluginTypeEffect);
} }

View File

@ -46,7 +46,7 @@ bool OpenProjectCommand::Apply(const CommandContext & context){
if(mFileName.IsEmpty()) if(mFileName.IsEmpty())
{ {
auto project = context.GetProject(); auto project = context.GetProject();
project->OnOpen(*project); GetMenuCommandHandler(*project).OnOpen(*project);
} }
else else
{ {

View File

@ -73,7 +73,8 @@ bool SetPreferenceCommand::Apply(const CommandContext & context)
{ {
bool bOK = gPrefs->Write(mName, mValue) && gPrefs->Flush(); bool bOK = gPrefs->Write(mName, mValue) && gPrefs->Flush();
if( bOK && mbReload ){ if( bOK && mbReload ){
context.GetProject()->OnReloadPreferences( context ); auto &project = context.project;
GetMenuCommandHandler(project).OnReloadPreferences( context );
} }
return bOK; return bOK;
} }

View File

@ -763,12 +763,13 @@ void Effect::SetDuration(double seconds)
bool Effect::Apply() bool Effect::Apply()
{ {
CommandContext context( *GetActiveProject() ); auto &project = *GetActiveProject();
CommandContext context( project );
// This is absolute hackage...but easy and I can't think of another way just now. // This is absolute hackage...but easy and I can't think of another way just now.
// //
// It should callback to the EffectManager to kick off the processing // It should callback to the EffectManager to kick off the processing
return GetActiveProject()->DoEffect(GetID(), context, return GetMenuCommandHandler(project).DoEffect(GetID(), context,
AudacityProject::OnEffectFlags::kConfigured); MenuCommandHandler::OnEffectFlags::kConfigured);
} }
void Effect::Preview() void Effect::Preview()
@ -3278,7 +3279,9 @@ void EffectUIHost::OnApply(wxCommandEvent & evt)
mProject->mViewInfo.selectedRegion.isPoint()) mProject->mViewInfo.selectedRegion.isPoint())
{ {
auto flags = AlwaysEnabledFlag; auto flags = AlwaysEnabledFlag;
bool allowed = mProject->ReportIfActionNotAllowed( bool allowed =
GetMenuCommandHandler(*mProject).ReportIfActionNotAllowed(
*mProject,
mEffect->GetTranslatedName(), mEffect->GetTranslatedName(),
flags, flags,
WaveTracksSelectedFlag | TimeSelectedFlag, WaveTracksSelectedFlag | TimeSelectedFlag,

View File

@ -305,8 +305,8 @@ void EffectRack::OnApply(wxCommandEvent & WXUNUSED(evt))
{ {
if (mPowerState[i]) if (mPowerState[i])
{ {
if (!project->DoEffect(mEffects[i]->GetID(), if (!GetMenuCommandHandler(*project).DoEffect(mEffects[i]->GetID(),
*project, *project,
AudacityProject::OnEffectFlags::kConfigured)) AudacityProject::OnEffectFlags::kConfigured))
// If any effect fails (or throws), then stop. // If any effect fails (or throws), then stop.
return; return;

View File

@ -390,7 +390,9 @@ bool Exporter::Process(AudacityProject *project, bool selectedOnly, double t0, d
// Let user edit MetaData // Let user edit MetaData
if (mPlugins[mFormat]->GetCanMetaData(mSubFormat)) { if (mPlugins[mFormat]->GetCanMetaData(mSubFormat)) {
if (!(project->DoEditMetadata(_("Edit Metadata Tags"), _("Exported Tags"), mProject->GetShowId3Dialog()))) { if (!(GetMenuCommandHandler(*project).DoEditMetadata( *project,
_("Edit Metadata Tags"), _("Exported Tags"),
mProject->GetShowId3Dialog()))) {
return false; return false;
} }
} }
@ -1031,8 +1033,9 @@ bool Exporter::SetAutoExportOptions(AudacityProject *project) {
// Let user edit MetaData // Let user edit MetaData
if (mPlugins[mFormat]->GetCanMetaData(mSubFormat)) { if (mPlugins[mFormat]->GetCanMetaData(mSubFormat)) {
if (!(project->DoEditMetadata(_("Edit Metadata Tags"), if (!(GetMenuCommandHandler(*project).DoEditMetadata( *project,
_("Exported Tags"), mProject->GetShowId3Dialog()))) { _("Edit Metadata Tags"),
_("Exported Tags"), mProject->GetShowId3Dialog()))) {
return false; return false;
} }
} }

View File

@ -389,7 +389,7 @@ void LOFImportFileHandle::lofOpenFiles(wxString* ln)
// If file is a midi // If file is a midi
if (Importer::IsMidi(targetfile)) if (Importer::IsMidi(targetfile))
{ {
mProject = AudacityProject::DoImportMIDI(mProject, targetfile); mProject = MenuCommandHandler::DoImportMIDI(mProject, targetfile);
} }
// If not a midi, open audio file // If not a midi, open audio file

View File

@ -1108,7 +1108,8 @@ bool ControlToolBar::DoRecord(AudacityProject &project,
CommandFlag flags = AlwaysEnabledFlag; // 0 means recalc flags. CommandFlag flags = AlwaysEnabledFlag; // 0 means recalc flags.
// NB: The call may have the side effect of changing flags. // NB: The call may have the side effect of changing flags.
bool allowed = project.TryToMakeActionAllowed( bool allowed = GetMenuCommandHandler(project).TryToMakeActionAllowed(
project,
flags, flags,
AudioIONotBusyFlag | CanStopAudioStreamFlag, AudioIONotBusyFlag | CanStopAudioStreamFlag,
AudioIONotBusyFlag | CanStopAudioStreamFlag); AudioIONotBusyFlag | CanStopAudioStreamFlag);

View File

@ -299,7 +299,7 @@ void EditToolBar::OnButton(wxCommandEvent &event)
CommandManager* cm = p->GetCommandManager(); CommandManager* cm = p->GetCommandManager();
if (!cm) return; if (!cm) return;
auto flags = p->GetUpdateFlags(); auto flags = GetMenuCommandHandler(*p).GetUpdateFlags(*p);
const CommandContext context( *GetActiveProject() ); const CommandContext context( *GetActiveProject() );
cm->HandleTextualCommand(EditToolbarButtonList[id].commandName, context, flags, NoFlagsSpecifed); cm->HandleTextualCommand(EditToolbarButtonList[id].commandName, context, flags, NoFlagsSpecifed);
} }

View File

@ -814,7 +814,7 @@ void WaveTrackMenuTable::OnSpectrogramSettings(wxCommandEvent &)
//Bug 1725 Toolbar was left greyed out. //Bug 1725 Toolbar was left greyed out.
//This solution is overkill, but does fix the problem and is what the //This solution is overkill, but does fix the problem and is what the
//prefs dialog normally does. //prefs dialog normally does.
AudacityProject::RebuildAllMenuBars(); MenuCommandHandler::RebuildAllMenuBars();
mpData->result = RefreshCode::RefreshAll; mpData->result = RefreshCode::RefreshAll;
} }
} }

View File

@ -617,7 +617,7 @@ void Scrubber::ContinueScrubbingUI()
// Dragging scrub can stop with mouse up // Dragging scrub can stop with mouse up
// Stop and set cursor // Stop and set cursor
bool bShift = state.ShiftDown(); bool bShift = state.ShiftDown();
mProject->DoPlayStopSelect(true, bShift); GetMenuCommandHandler(*mProject).DoPlayStopSelect(*mProject, true, bShift);
wxCommandEvent evt; wxCommandEvent evt;
mProject->GetControlToolBar()->OnStop(evt); mProject->GetControlToolBar()->OnStop(evt);
return; return;
@ -683,7 +683,8 @@ void Scrubber::StopScrubbing()
const wxMouseState state(::wxGetMouseState()); const wxMouseState state(::wxGetMouseState());
// Stop and set cursor // Stop and set cursor
bool bShift = state.ShiftDown(); bool bShift = state.ShiftDown();
mProject->DoPlayStopSelect(true, bShift); GetMenuCommandHandler(*mProject).
DoPlayStopSelect(*mProject, true, bShift);
} }
mScrubStartPosition = -1; mScrubStartPosition = -1;

View File

@ -549,7 +549,8 @@ UIHandle::Result SelectHandle::Click
// text boxes. // text boxes.
bool bShift = event.ShiftDown(); bool bShift = event.ShiftDown();
bool unsafe = pProject->IsAudioActive(); bool unsafe = pProject->IsAudioActive();
pProject->HandleListSelection(pTrack, bShift, true, !unsafe); GetMenuCommandHandler(*pProject)
.HandleListSelection(*pProject, pTrack, bShift, true, !unsafe);
// Do not start a drag // Do not start a drag
return RefreshAll | Cancelled; return RefreshAll | Cancelled;
} }

View File

@ -233,21 +233,21 @@ void TrackMenuTable::OnSetName(wxCommandEvent &)
void TrackMenuTable::OnMoveTrack(wxCommandEvent &event) void TrackMenuTable::OnMoveTrack(wxCommandEvent &event)
{ {
AudacityProject *const project = GetActiveProject(); AudacityProject *const project = GetActiveProject();
AudacityProject::MoveChoice choice; MenuCommandHandler::MoveChoice choice;
switch (event.GetId()) { switch (event.GetId()) {
default: default:
wxASSERT(false); wxASSERT(false);
case OnMoveUpID: case OnMoveUpID:
choice = AudacityProject::OnMoveUpID; break; choice = MenuCommandHandler::OnMoveUpID; break;
case OnMoveDownID: case OnMoveDownID:
choice = AudacityProject::OnMoveDownID; break; choice = MenuCommandHandler::OnMoveDownID; break;
case OnMoveTopID: case OnMoveTopID:
choice = AudacityProject::OnMoveTopID; break; choice = MenuCommandHandler::OnMoveTopID; break;
case OnMoveBottomID: case OnMoveBottomID:
choice = AudacityProject::OnMoveBottomID; break; choice = MenuCommandHandler::OnMoveBottomID; break;
} }
project->MoveTrack(mpData->pTrack, choice); GetMenuCommandHandler(*project).MoveTrack(*project, mpData->pTrack, choice);
// MoveTrack already refreshed TrackPanel, which means repaint will happen. // MoveTrack already refreshed TrackPanel, which means repaint will happen.
// This is a harmless redundancy: // This is a harmless redundancy:

View File

@ -100,8 +100,8 @@ UIHandle::Result TrackSelectHandle::Click
CalculateRearrangingThresholds(event); CalculateRearrangingThresholds(event);
} }
pProject->HandleListSelection GetMenuCommandHandler(*pProject).HandleListSelection(*pProject,
(pTrack.get(), event.ShiftDown(), event.ControlDown(), !unsafe); pTrack.get(), event.ShiftDown(), event.ControlDown(), !unsafe);
mClicked = true; mClicked = true;
return result; return result;

View File

@ -153,7 +153,7 @@ void MultiDialog::OnOK(wxCommandEvent & WXUNUSED(event))
void MultiDialog::OnShowLog(wxCommandEvent & WXUNUSED(event)) void MultiDialog::OnShowLog(wxCommandEvent & WXUNUSED(event))
{ {
auto project = GetActiveProject(); auto project = GetActiveProject();
project->OnShowLog(*project); GetMenuCommandHandler(*project).OnShowLog(*project);
} }

View File

@ -2881,7 +2881,7 @@ auto AdornedRulerPanel::QPHandle::Click
if(scrubber.HasMark()) { if(scrubber.HasMark()) {
// We can't stop scrubbing yet (see comments in Bug 1391), // We can't stop scrubbing yet (see comments in Bug 1391),
// but we can pause it. // but we can pause it.
pProject->OnPause( *pProject ); GetMenuCommandHandler(*pProject).OnPause(*pProject);
} }
// Store the initial play region state // Store the initial play region state
@ -2905,7 +2905,7 @@ void AdornedRulerPanel::HandleQPClick(wxMouseEvent &evt, wxCoord mousePosX)
// Temporarily unlock locked play region // Temporarily unlock locked play region
if (mPlayRegionLock && evt.LeftDown()) { if (mPlayRegionLock && evt.LeftDown()) {
//mPlayRegionLock = true; //mPlayRegionLock = true;
mProject->OnUnlockPlayRegion(*mProject); GetMenuCommandHandler(*mProject).OnUnlockPlayRegion(*mProject);
} }
mLeftDownClickUnsnapped = mQuickPlayPosUnsnapped; mLeftDownClickUnsnapped = mQuickPlayPosUnsnapped;
@ -3155,7 +3155,7 @@ void AdornedRulerPanel::HandleQPRelease(wxMouseEvent &evt)
if (mPlayRegionLock) { if (mPlayRegionLock) {
// Restore Locked Play region // Restore Locked Play region
SetPlayRegion(mOldPlayRegionStart, mOldPlayRegionEnd); SetPlayRegion(mOldPlayRegionStart, mOldPlayRegionEnd);
mProject->OnLockPlayRegion(*mProject); GetMenuCommandHandler(*mProject).OnLockPlayRegion(*mProject);
// and release local lock // and release local lock
mPlayRegionLock = false; mPlayRegionLock = false;
} }
@ -3177,7 +3177,7 @@ auto AdornedRulerPanel::QPHandle::Cancel
mParent->mOldPlayRegionStart, mParent->mOldPlayRegionEnd); mParent->mOldPlayRegionStart, mParent->mOldPlayRegionEnd);
if (mParent->mPlayRegionLock) { if (mParent->mPlayRegionLock) {
// Restore Locked Play region // Restore Locked Play region
pProject->OnLockPlayRegion(*pProject); GetMenuCommandHandler(*pProject).OnLockPlayRegion(*pProject);
// and release local lock // and release local lock
mParent->mPlayRegionLock = false; mParent->mPlayRegionLock = false;
} }
@ -3313,7 +3313,7 @@ void AdornedRulerPanel::UpdateButtonStates()
void AdornedRulerPanel::OnTogglePinnedState(wxCommandEvent & /*event*/) void AdornedRulerPanel::OnTogglePinnedState(wxCommandEvent & /*event*/)
{ {
mProject->OnTogglePinnedHead(*mProject); GetMenuCommandHandler(*mProject).OnTogglePinnedHead(*mProject);
UpdateButtonStates(); UpdateButtonStates();
} }
@ -3451,9 +3451,9 @@ void AdornedRulerPanel::OnAutoScroll(wxCommandEvent&)
void AdornedRulerPanel::OnLockPlayRegion(wxCommandEvent&) void AdornedRulerPanel::OnLockPlayRegion(wxCommandEvent&)
{ {
if (mProject->IsPlayRegionLocked()) if (mProject->IsPlayRegionLocked())
mProject->OnUnlockPlayRegion(*mProject); GetMenuCommandHandler(*mProject).OnUnlockPlayRegion(*mProject);
else else
mProject->OnLockPlayRegion(*mProject); GetMenuCommandHandler(*mProject).OnLockPlayRegion(*mProject);
} }