From fc6570646db59d5bbc710e3c86b1ca93cfbbe223 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 15 Oct 2018 14:07:32 -0400 Subject: [PATCH] MenuCommandHandler is not a base class of MenuManager... ... This forces a better placement of state variables in the appropriate classes. In future perhaps, MenuManager should be splintered into several classes, one for each of the main toolbar menus. --- src/BatchCommands.cpp | 2 +- src/BatchProcessDialog.cpp | 2 +- src/Menus.cpp | 50 +++++++++++++++++++-------------- src/Menus.h | 29 +++++++++++-------- src/MenusMac.cpp | 2 +- src/Project.cpp | 30 +++++++++++--------- src/Project.h | 6 ++-- src/commands/CommandManager.cpp | 4 +-- src/effects/Effect.cpp | 2 +- src/toolbars/ControlToolBar.cpp | 2 +- src/toolbars/EditToolBar.cpp | 2 +- 11 files changed, 75 insertions(+), 56 deletions(-) diff --git a/src/BatchCommands.cpp b/src/BatchCommands.cpp index 0c70073c9..6f15f9424 100644 --- a/src/BatchCommands.cpp +++ b/src/BatchCommands.cpp @@ -791,7 +791,7 @@ bool MacroCommands::ApplyCommandInBatchMode( const wxString &friendlyCommand, { AudacityProject *project = GetActiveProject(); // Recalc flags and enable items that may have become enabled. - GetMenuCommandHandler(*project).UpdateMenus(*project, false); + GetMenuManager(*project).UpdateMenus(*project, false); // enter batch mode... bool prevShowMode = project->GetShowId3Dialog(); project->mBatchMode++; diff --git a/src/BatchProcessDialog.cpp b/src/BatchProcessDialog.cpp index bfc84b160..f8bb20a3e 100644 --- a/src/BatchProcessDialog.cpp +++ b/src/BatchProcessDialog.cpp @@ -749,7 +749,7 @@ void MacrosWindow::UpdateMenus() { // OK even on mac, as dialog is modal. auto p = GetActiveProject(); - GetMenuCommandHandler(*p).RebuildMenuBar(*p); + GetMenuManager(*p).RebuildMenuBar(*p); } void MacrosWindow::UpdateDisplay( bool bExpanded ) diff --git a/src/Menus.cpp b/src/Menus.cpp index 07dc76576..704b61d8e 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -158,9 +158,12 @@ menu items. #include "./commands/AudacityCommand.h" #include "commands/CommandContext.h" -MenuManager &GetMenuCommandHandler(AudacityProject &project) +MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project) { return *project.mMenuCommandHandler; } +MenuManager &GetMenuManager(AudacityProject &project) +{ return *project.mMenuManager; } + MenuCommandHandler::MenuCommandHandler() { //Initialize the last selection adjustment time. @@ -330,6 +333,14 @@ static bool SortEffectsByType(const PluginDescriptor *a, const PluginDescriptor return akey.CmpNoCase(bkey) < 0; } +void MenuCommandHandler::UpdatePrefs() +{ + gPrefs->Read(wxT("/GUI/CircularTrackNavigation"), &mCircularTrackNavigation, + false); + gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &mSeekShort, 1.0); + gPrefs->Read(wxT("/AudioIO/SeekLongPeriod"), &mSeekLong, 15.0); +} + void MenuManager::UpdatePrefs() { bool bSelectAllIfNone; @@ -343,12 +354,6 @@ void MenuManager::UpdatePrefs() mWhatIfNoSelection = bSelectAllIfNone ? 1 : 2; #endif mStopIfWasPaused = true; // not configurable for now, but could be later. - - gPrefs->Read(wxT("/GUI/CircularTrackNavigation"), &mCircularTrackNavigation, - false); - - gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &mSeekShort, 1.0); - gPrefs->Read(wxT("/AudioIO/SeekLongPeriod"), &mSeekLong, 15.0); } /// CreateMenusAndCommands builds the menus, and also rebuilds them after @@ -2241,7 +2246,7 @@ void AudacityProject::RebuildOtherMenus() { } -CommandFlag MenuCommandHandler::GetFocusedFrame(AudacityProject &project) +CommandFlag MenuManager::GetFocusedFrame(AudacityProject &project) { wxWindow *w = wxWindow::FindFocus(); @@ -2441,7 +2446,7 @@ CommandFlag MenuManager::GetUpdateFlags // time range is selected. void AudacityProject::SelectAllIfNone() { - auto flags = GetMenuCommandHandler(*this).GetUpdateFlags(*this); + auto flags = GetMenuManager(*this).GetUpdateFlags(*this); if(!(flags & TracksSelectedFlag) || (mViewInfo.selectedRegion.isPoint())) GetMenuCommandHandler(*this).OnSelectSomething(*this); @@ -2450,7 +2455,7 @@ void AudacityProject::SelectAllIfNone() // Stop playing or recording, if paused. void AudacityProject::StopIfPaused() { - auto flags = GetMenuCommandHandler(*this).GetUpdateFlags(*this); + auto flags = GetMenuManager(*this).GetUpdateFlags(*this); if( flags & PausedFlag ) GetMenuCommandHandler(*this).OnStop(*this); } @@ -2460,7 +2465,7 @@ void MenuManager::ModifyAllProjectToolbarMenus() AProjectArray::iterator i; for (i = gAudacityProjects.begin(); i != gAudacityProjects.end(); ++i) { auto &project = **i; - GetMenuCommandHandler(project).ModifyToolbarMenus(project); + GetMenuManager(project).ModifyToolbarMenus(project); } } @@ -2545,7 +2550,7 @@ void MenuManager::UpdateMenus(AudacityProject &project, bool checkActive) if (&project != GetActiveProject()) return; - auto flags = GetMenuCommandHandler(project).GetUpdateFlags(project, checkActive); + auto flags = GetMenuManager(project).GetUpdateFlags(project, checkActive); auto flags2 = flags; // We can enable some extra items if we have select-all-on-none. @@ -4854,7 +4859,7 @@ bool MenuCommandHandler::DoEffect( // For now, we're limiting realtime preview to a single effect, so // make sure the menus reflect that fact that one may have just been // opened. - GetMenuCommandHandler(project).UpdateMenus(project, false); + GetMenuManager(project).UpdateMenus(project, false); } } ); @@ -4892,7 +4897,7 @@ bool MenuCommandHandler::DoEffect( // or analyze effects. if (type == EffectTypeProcess) { wxString shortDesc = em.GetCommandName(ID); - mLastEffect = ID; + GetMenuManager(project).mLastEffect = ID; wxString lastEffectDesc; /* i18n-hint: %s will be the name of the effect which will be * repeated if this menu item is chosen */ @@ -4938,9 +4943,11 @@ void MenuCommandHandler::OnEffect(const CommandContext &context) void MenuCommandHandler::OnRepeatLastEffect(const CommandContext &context) { - if (!mLastEffect.IsEmpty()) + auto lastEffect = GetMenuManager(context.project).mLastEffect; + if (!lastEffect.IsEmpty()) { - DoEffect(mLastEffect, context, OnEffectFlags::kConfigured); + DoEffect(lastEffect, + context, OnEffectFlags::kConfigured); } } @@ -4950,7 +4957,7 @@ void MenuCommandHandler::RebuildAllMenuBars() for( size_t i = 0; i < gAudacityProjects.size(); i++ ) { AudacityProject *p = gAudacityProjects[i].get(); - GetMenuCommandHandler(*p).RebuildMenuBar(*p); + GetMenuManager(*p).RebuildMenuBar(*p); #if defined(__WXGTK__) // Workaround for: // @@ -5362,7 +5369,7 @@ void MenuCommandHandler::OnPreferences(const CommandContext &context) for (size_t i = 0; i < gAudacityProjects.size(); i++) { AudacityProject *p = gAudacityProjects[i].get(); - GetMenuCommandHandler(*p).RebuildMenuBar(*p); + GetMenuManager(*p).RebuildMenuBar(*p); p->RebuildOtherMenus(); // TODO: The comment below suggests this workaround is obsolete. #if defined(__WXGTK__) @@ -5400,7 +5407,7 @@ void MenuCommandHandler::OnReloadPreferences(const CommandContext &context ) for (size_t i = 0; i < gAudacityProjects.size(); i++) { AudacityProject *p = gAudacityProjects[i].get(); - GetMenuCommandHandler(*p).RebuildMenuBar(*p); + GetMenuManager(*p).RebuildMenuBar(*p); p->RebuildOtherMenus(); // TODO: The comment below suggests this workaround is obsolete. #if defined(__WXGTK__) @@ -8457,7 +8464,7 @@ void MenuCommandHandler::HandleAlign : _("Align Together"); } - if ((unsigned)index >= mAlignLabelsCount) { // This is an alignLabelsNoSync command. + if ((unsigned)index >= GetMenuManager(project).mAlignLabelsCount) { // This is an alignLabelsNoSync command. for (auto t : tracks->SelectedLeaders< AudioTrack >()) { // This shifts different tracks in different ways, so no sync-lock move. // Only align Wave and Note tracks end to end. @@ -8497,7 +8504,8 @@ void MenuCommandHandler::OnAlignNoSync(const CommandContext &context) auto &project = context.project; // Add length of alignLabels array so that we can handle this in AudacityProject::HandleAlign. - HandleAlign(project, context.index + mAlignLabelsCount, false); + HandleAlign(project, + context.index + GetMenuManager(project).mAlignLabelsCount, false); } void MenuCommandHandler::OnAlign(const CommandContext &context) diff --git a/src/Menus.h b/src/Menus.h index 83017deda..402bffd9b 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -19,8 +19,6 @@ struct MenuCommandHandler : public wxEvtHandler { MenuCommandHandler(); ~MenuCommandHandler(); -CommandFlag GetFocusedFrame(AudacityProject &project); - //Adds label and returns index of label in labeltrack. @@ -450,7 +448,6 @@ void OnAlignNoSync(const CommandContext &context ); void OnAlign(const CommandContext &context ); //void OnAlignMoveSel(int index); void HandleAlign(AudacityProject &project, int index, bool moveSel); -size_t mAlignLabelsCount; #ifdef EXPERIMENTAL_SCOREALIGN void OnScoreAlign(const CommandContext &context ); @@ -586,21 +583,16 @@ double GridMove(AudacityProject &project, double t, int minPix); public: -// Last effect applied to this project - PluginID mLastEffect{}; - CommandFlag mLastFlags; -// 0 is grey out, 1 is Autoselect, 2 is Give warnings. - int mWhatIfNoSelection; - bool mStopIfWasPaused; double mSeekShort; double mSeekLong; bool mCircularTrackNavigation{}; wxLongLong mLastSelectionAdjustment; + void UpdatePrefs(); }; -class MenuCreator : public MenuCommandHandler +class MenuCreator { public: MenuCreator(); @@ -625,6 +617,12 @@ public: // Recent files wxMenu *mRecentFilesMenu; + CommandFlag mLastFlags; + + // Last effect applied to this project + PluginID mLastEffect{}; + + size_t mAlignLabelsCount; }; class MenuManager : public MenuCreator @@ -651,10 +649,19 @@ public: bool TryToMakeActionAllowed ( AudacityProject &project, CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask ); + + +private: + CommandFlag GetFocusedFrame(AudacityProject &project); + + // 0 is grey out, 1 is Autoselect, 2 is Give warnings. + int mWhatIfNoSelection; + bool mStopIfWasPaused; }; -MenuManager &GetMenuCommandHandler(AudacityProject &project); +MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project); +MenuManager &GetMenuManager(AudacityProject &project); #endif diff --git a/src/MenusMac.cpp b/src/MenusMac.cpp index 01ffdc66d..f92bb1eaf 100644 --- a/src/MenusMac.cpp +++ b/src/MenusMac.cpp @@ -42,7 +42,7 @@ void MenuCommandHandler::DoMacMinimize(AudacityProject *project) #endif // So that the Minimize menu command disables - GetMenuCommandHandler(*project).UpdateMenus(*project); + GetMenuManager(*project).UpdateMenus(*project); } } diff --git a/src/Project.cpp b/src/Project.cpp index 26189e36c..3c9dbf71e 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -979,7 +979,8 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, // Initialize view info (shared with TrackPanel) // - mMenuCommandHandler = std::make_unique(); + mMenuCommandHandler = std::make_unique(); + mMenuManager = std::make_unique(); UpdatePrefs(); @@ -1140,7 +1141,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, mTrackPanel->AddOverlay(mScrubOverlay.get()); #endif - mMenuCommandHandler->CreateMenusAndCommands(*this); + mMenuManager->CreateMenusAndCommands(*this); mTrackPanel->SetBackgroundCell(mBackgroundCell); @@ -1361,6 +1362,7 @@ void AudacityProject::UpdatePrefs() SetProjectTitle(); GetMenuCommandHandler(*this).UpdatePrefs(); + GetMenuManager(*this).UpdatePrefs(); if (mTrackPanel) { mTrackPanel->UpdatePrefs(); @@ -2040,7 +2042,7 @@ void AudacityProject::FixScrollbars() mTrackPanel->Refresh(false); } - GetMenuCommandHandler(*this).UpdateMenus(*this); + GetMenuManager(*this).UpdateMenus(*this); if (oldhstate != newhstate || oldvstate != newvstate) { UpdateLayout(); @@ -2292,7 +2294,7 @@ bool MenuManager::TryToMakeActionAllowed bool bAllowed; if( !flags ) - flags = GetMenuCommandHandler(project).GetUpdateFlags(project); + flags = GetMenuManager(project).GetUpdateFlags(project); bAllowed = ((flags & mask) == (flagsRqd & mask)); if( bAllowed ) @@ -2305,7 +2307,7 @@ bool MenuManager::TryToMakeActionAllowed if( mStopIfWasPaused && (MissingFlags & AudioIONotBusyFlag ) ){ project.StopIfPaused(); // Hope this will now reflect stopped audio. - flags = GetMenuCommandHandler(project).GetUpdateFlags(project); + flags = GetMenuManager(project).GetUpdateFlags(project); bAllowed = ((flags & mask) == (flagsRqd & mask)); if( bAllowed ) return true; @@ -2335,7 +2337,7 @@ bool MenuManager::TryToMakeActionAllowed // This was 'OnSelectAll'. Changing it to OnSelectSomething means if // selecting all tracks is enough, we just do that. GetMenuCommandHandler(project).OnSelectSomething(project); - flags = GetMenuCommandHandler(project).GetUpdateFlags(project); + flags = GetMenuManager(project).GetUpdateFlags(project); bAllowed = ((flags & mask) == (flagsRqd & mask)); return bAllowed; } @@ -2356,7 +2358,7 @@ void AudacityProject::OnMenu(wxCommandEvent & event) } #endif bool handled = mCommandManager.HandleMenuID( - event.GetId(), GetMenuCommandHandler(*this).GetUpdateFlags(*this), + event.GetId(), GetMenuManager(*this).GetUpdateFlags(*this), NoFlagsSpecifed); if (handled) @@ -2369,7 +2371,7 @@ void AudacityProject::OnMenu(wxCommandEvent & event) void AudacityProject::OnUpdateUI(wxUpdateUIEvent & WXUNUSED(event)) { - GetMenuCommandHandler(*this).UpdateMenus(*this); + GetMenuManager(*this).UpdateMenus(*this); } void AudacityProject::MacShowUndockedToolbars(bool show) @@ -4588,9 +4590,9 @@ void AudacityProject::InitialState() if (mHistoryWindow) mHistoryWindow->UpdateDisplay(); - GetMenuCommandHandler(*this).ModifyUndoMenuItems(*this); + GetMenuManager(*this).ModifyUndoMenuItems(*this); - GetMenuCommandHandler(*this).UpdateMenus(*this); + GetMenuManager(*this).UpdateMenus(*this); this->UpdateLyrics(); this->UpdateMixerBoard(); } @@ -4626,9 +4628,9 @@ void AudacityProject::PushState(const wxString &desc, if (mHistoryWindow) mHistoryWindow->UpdateDisplay(); - GetMenuCommandHandler(*this).ModifyUndoMenuItems(*this); + GetMenuManager(*this).ModifyUndoMenuItems(*this); - GetMenuCommandHandler(*this).UpdateMenus(*this); + GetMenuManager(*this).UpdateMenus(*this); // Some state pushes, like changing a track gain control (& probably others), // should not repopulate Lyrics Window and MixerBoard. @@ -4710,7 +4712,7 @@ void AudacityProject::PopState(const UndoState &state) HandleResize(); - GetMenuCommandHandler(*this).UpdateMenus(*this); + GetMenuManager(*this).UpdateMenus(*this); this->UpdateLyrics(); this->UpdateMixerBoard(); @@ -4726,7 +4728,7 @@ void AudacityProject::SetStateTo(unsigned int n) HandleResize(); mTrackPanel->SetFocusedTrack(NULL); mTrackPanel->Refresh(false); - GetMenuCommandHandler(*this).ModifyUndoMenuItems(*this); + GetMenuManager(*this).ModifyUndoMenuItems(*this); this->UpdateLyrics(); this->UpdateMixerBoard(); } diff --git a/src/Project.h b/src/Project.h index 72187b10b..beddcc02f 100644 --- a/src/Project.h +++ b/src/Project.h @@ -811,10 +811,12 @@ private: #endif private: - std::unique_ptr mMenuCommandHandler; + std::unique_ptr mMenuCommandHandler; + std::unique_ptr mMenuManager; public: - friend MenuManager &GetMenuCommandHandler(AudacityProject &project); + friend MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project); + friend MenuManager &GetMenuManager(AudacityProject &project); class PlaybackScroller final : public wxEvtHandler { diff --git a/src/commands/CommandManager.cpp b/src/commands/CommandManager.cpp index 508bad569..3f04ffc56 100644 --- a/src/commands/CommandManager.cpp +++ b/src/commands/CommandManager.cpp @@ -1484,7 +1484,7 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent & return false; } - auto flags = GetMenuCommandHandler(*project).GetUpdateFlags(*project); + auto flags = GetMenuManager(*project).GetUpdateFlags(*project); wxKeyEvent temp = evt; @@ -1579,7 +1579,7 @@ bool CommandManager::HandleCommandEntry(const CommandListEntry * entry, NiceName.Replace(".","");// remove ... // NB: The call may have the side effect of changing flags. bool allowed = - GetMenuCommandHandler(*proj).ReportIfActionNotAllowed( *proj, + GetMenuManager(*proj).ReportIfActionNotAllowed( *proj, NiceName, flags, entry->flags, combinedMask ); // If the function was disallowed, it STILL should count as having been // handled (by doing nothing or by telling the user of the problem). diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index 13fc71777..19a835719 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -3240,7 +3240,7 @@ void EffectUIHost::OnApply(wxCommandEvent & evt) { auto flags = AlwaysEnabledFlag; bool allowed = - GetMenuCommandHandler(*mProject).ReportIfActionNotAllowed( + GetMenuManager(*mProject).ReportIfActionNotAllowed( *mProject, mEffect->GetTranslatedName(), flags, diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index afcf9ca4d..7586e7d9b 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -1054,7 +1054,7 @@ bool ControlToolBar::DoRecord(AudacityProject &project, CommandFlag flags = AlwaysEnabledFlag; // 0 means recalc flags. // NB: The call may have the side effect of changing flags. - bool allowed = GetMenuCommandHandler(project).TryToMakeActionAllowed( + bool allowed = GetMenuManager(project).TryToMakeActionAllowed( project, flags, AudioIONotBusyFlag | CanStopAudioStreamFlag, diff --git a/src/toolbars/EditToolBar.cpp b/src/toolbars/EditToolBar.cpp index 9cf46c111..e33f50eaa 100644 --- a/src/toolbars/EditToolBar.cpp +++ b/src/toolbars/EditToolBar.cpp @@ -299,7 +299,7 @@ void EditToolBar::OnButton(wxCommandEvent &event) CommandManager* cm = p->GetCommandManager(); if (!cm) return; - auto flags = GetMenuCommandHandler(*p).GetUpdateFlags(*p); + auto flags = GetMenuManager(*p).GetUpdateFlags(*p); const CommandContext context( *GetActiveProject() ); cm->HandleTextualCommand(EditToolbarButtonList[id].commandName, context, flags, NoFlagsSpecifed); }