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.
This commit is contained in:
Paul Licameli 2018-10-15 14:07:32 -04:00 committed by James Crook
parent d693b36bdb
commit fc6570646d
11 changed files with 75 additions and 56 deletions

View File

@ -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++;

View File

@ -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 )

View File

@ -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)

View File

@ -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

View File

@ -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);
}
}

View File

@ -979,7 +979,8 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
// Initialize view info (shared with TrackPanel)
//
mMenuCommandHandler = std::make_unique<MenuManager>();
mMenuCommandHandler = std::make_unique<MenuCommandHandler>();
mMenuManager = std::make_unique<MenuManager>();
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();
}

View File

@ -811,10 +811,12 @@ private:
#endif
private:
std::unique_ptr<MenuManager> mMenuCommandHandler;
std::unique_ptr<MenuCommandHandler> mMenuCommandHandler;
std::unique_ptr<MenuManager> mMenuManager;
public:
friend MenuManager &GetMenuCommandHandler(AudacityProject &project);
friend MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project);
friend MenuManager &GetMenuManager(AudacityProject &project);
class PlaybackScroller final : public wxEvtHandler
{

View File

@ -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).

View File

@ -3240,7 +3240,7 @@ void EffectUIHost::OnApply(wxCommandEvent & evt)
{
auto flags = AlwaysEnabledFlag;
bool allowed =
GetMenuCommandHandler(*mProject).ReportIfActionNotAllowed(
GetMenuManager(*mProject).ReportIfActionNotAllowed(
*mProject,
mEffect->GetTranslatedName(),
flags,

View File

@ -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,

View File

@ -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);
}