Bug 2582 - Enh: Repeat last Process, Part 2 (#734)

This commit is contained in:
JohnColket 2021-02-03 06:02:49 -05:00 committed by GitHub
parent eb888bb03b
commit a3d9f41fb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 180 additions and 63 deletions

View File

@ -253,6 +253,7 @@ const ReservedCommandFlag&
const ReservedCommandFlag& const ReservedCommandFlag&
HasLastAnalyzerFlag() { static ReservedCommandFlag flag{ HasLastAnalyzerFlag() { static ReservedCommandFlag flag{
[](const AudacityProject &project) { [](const AudacityProject &project) {
if (MenuManager::Get(project).mLastAnalyzerRegistration == MenuCreator::repeattypeunique) return true;
return !MenuManager::Get(project).mLastAnalyzer.empty(); return !MenuManager::Get(project).mLastAnalyzer.empty();
} }
}; return flag; }; return flag;
@ -260,7 +261,9 @@ const ReservedCommandFlag&
const ReservedCommandFlag& const ReservedCommandFlag&
HasLastToolFlag() { static ReservedCommandFlag flag{ HasLastToolFlag() { static ReservedCommandFlag flag{
[](const AudacityProject &project) { [](const AudacityProject &project) {
return !MenuManager::Get(project).mLastTool.empty(); auto& menuManager = MenuManager::Get(project);
if (menuManager.mLastToolRegistration == MenuCreator::repeattypeunique) return true;
return !menuManager.mLastTool.empty();
} }
}; return flag; }; return flag;
} }

View File

@ -1160,6 +1160,7 @@ struct Handler : CommandHandlerObject {
void OnPlotSpectrum(const CommandContext &context) void OnPlotSpectrum(const CommandContext &context)
{ {
auto &project = context.project; auto &project = context.project;
CommandManager::Get(project).RegisterLastAnalyzer(context); //Register Plot Spectrum as Last Analyzer
auto freqWindow = auto freqWindow =
&project.AttachedWindows::Get< FrequencyPlotDialog >( sFrequencyWindowKey ); &project.AttachedWindows::Get< FrequencyPlotDialog >( sFrequencyWindowKey );

View File

@ -48,6 +48,8 @@
MenuCreator::MenuCreator() MenuCreator::MenuCreator()
{ {
mLastAnalyzerRegistration = repeattypenone;
mLastToolRegistration = repeattypenone;
} }
MenuCreator::~MenuCreator() MenuCreator::~MenuCreator()

View File

@ -52,8 +52,21 @@ public:
PluginID mLastGenerator{}; PluginID mLastGenerator{};
PluginID mLastEffect{}; PluginID mLastEffect{};
PluginID mLastAnalyzer{}; PluginID mLastAnalyzer{};
int mLastAnalyzerRegistration;
int mLastAnalyzerRegisteredId;
PluginID mLastTool{}; PluginID mLastTool{};
bool mLastToolIsMacro; int mLastToolRegistration;
int mLastToolRegisteredId;
enum {
repeattypenone = 0,
repeattypeplugin = 1,
repeattypeunique = 2,
repeattypeapplymacro = 3
};
unsigned mRepeatGeneratorFlags;
unsigned mRepeatEffectFlags;
unsigned mRepeatAnalyzerFlags;
unsigned mRepeatToolFlags;
}; };
struct ToolbarMenuVisitor; struct ToolbarMenuVisitor;

View File

@ -235,6 +235,7 @@ CommandManager::CommandManager():
{ {
mbSeparatorAllowed = false; mbSeparatorAllowed = false;
SetMaxList(); SetMaxList();
mLastProcessId = 0;
} }
/// ///
@ -722,23 +723,6 @@ CommandListEntry *CommandManager::NewIdentifier(const CommandID & nameIn,
entry->id = wxID_EXIT; entry->id = wxID_EXIT;
else if (name == wxT("About")) else if (name == wxT("About"))
entry->id = wxID_ABOUT; entry->id = wxID_ABOUT;
#if defined(BE_CAREFUL)
// Don't be tempted to do this unless you're willing to change how
// HandleMenuID() decides if a menu action should be performed.
// (see comments 6-9 in bug #2642 for symptoms)
else if (name == wxT("Copy"))
entry->id = wxID_COPY;
else if (name == wxT("Cut"))
entry->id = wxID_CUT;
else if (name == wxT("Delete"))
entry->id = wxID_CLEAR;
else if (name == wxT("Paste"))
entry->id = wxID_PASTE;
else if (name == wxT("SelectAll"))
entry->id = wxID_SELECTALL;
#endif
#endif #endif
entry->name = name; entry->name = name;
@ -1192,6 +1176,7 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent &
return false; return false;
} }
/// HandleCommandEntry() takes a CommandListEntry and executes it /// HandleCommandEntry() takes a CommandListEntry and executes it
/// returning true iff successful. If you pass any flags, /// returning true iff successful. If you pass any flags,
///the command won't be executed unless the flags are compatible ///the command won't be executed unless the flags are compatible
@ -1219,15 +1204,54 @@ bool CommandManager::HandleCommandEntry(AudacityProject &project,
// 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.
if (!allowed) if (!allowed)
return true; return true;
mNiceName = NiceName;
}
else {
mNiceName = XO("");
} }
const CommandContext context{ project, evt, entry->index, entry->parameter }; const CommandContext context{ project, evt, entry->index, entry->parameter };
auto &handler = entry->finder(project); auto &handler = entry->finder(project);
(handler.*(entry->callback))(context); (handler.*(entry->callback))(context);
mLastProcessId = 0;
return true; return true;
} }
// Called by Contrast and Plot Spectrum Plug-ins to mark them as Last Analzers.
// Note that Repeat data has previously been collected
void CommandManager::RegisterLastAnalyzer(const CommandContext& context) {
if (mLastProcessId != 0) {
auto& menuManager = MenuManager::Get(context.project);
menuManager.mLastAnalyzerRegistration = MenuCreator::repeattypeunique;
menuManager.mLastAnalyzerRegisteredId = mLastProcessId;
auto lastEffectDesc = XO("Repeat %s").Format(mNiceName);
Modify(wxT("RepeatLastAnalyzer"), lastEffectDesc);
}
return;
}
// Called by Selected Tools to mark them as Last Tools.
// Note that Repeat data has previously been collected
void CommandManager::RegisterLastTool(const CommandContext& context) {
if (mLastProcessId != 0) {
auto& menuManager = MenuManager::Get(context.project);
menuManager.mLastToolRegistration = MenuCreator::repeattypeunique;
menuManager.mLastToolRegisteredId = mLastProcessId;
auto lastEffectDesc = XO("Repeat %s").Format(mNiceName);
Modify(wxT("RepeatLastTool"), lastEffectDesc);
}
return;
}
// Used to invoke Repeat Last Analyzer Process for built-in, non-nyquist plug-ins.
void CommandManager::DoRepeatProcess(const CommandContext& context, int id) {
mLastProcessId = 0; //Don't Process this as repeat
CommandListEntry* entry = mCommandNumericIDHash[id];
auto& handler = entry->finder(context.project);
(handler.*(entry->callback))(context);
}
///Call this when a menu event is received. ///Call this when a menu event is received.
///If it matches a command, it will call the appropriate ///If it matches a command, it will call the appropriate
///CommandManagerListener function. If you pass any flags, ///CommandManagerListener function. If you pass any flags,
@ -1236,6 +1260,7 @@ bool CommandManager::HandleCommandEntry(AudacityProject &project,
bool CommandManager::HandleMenuID( bool CommandManager::HandleMenuID(
AudacityProject &project, int id, CommandFlag flags, bool alwaysEnabled) AudacityProject &project, int id, CommandFlag flags, bool alwaysEnabled)
{ {
mLastProcessId = id;
CommandListEntry *entry = mCommandNumericIDHash[id]; CommandListEntry *entry = mCommandNumericIDHash[id];
auto hook = sMenuHook(); auto hook = sMenuHook();

View File

@ -209,6 +209,9 @@ class AUDACITY_DLL_API CommandManager final
// Lyrics and MixerTrackCluster classes use it. // Lyrics and MixerTrackCluster classes use it.
bool FilterKeyEvent(AudacityProject *project, const wxKeyEvent & evt, bool permit = false); bool FilterKeyEvent(AudacityProject *project, const wxKeyEvent & evt, bool permit = false);
bool HandleMenuID(AudacityProject &project, int id, CommandFlag flags, bool alwaysEnabled); bool HandleMenuID(AudacityProject &project, int id, CommandFlag flags, bool alwaysEnabled);
void RegisterLastAnalyzer(const CommandContext& context);
void RegisterLastTool(const CommandContext& context);
void DoRepeatProcess(const CommandContext& context, int);
enum TextualCommandResult { enum TextualCommandResult {
CommandFailure, CommandFailure,
@ -356,6 +359,8 @@ private:
bool mbSeparatorAllowed; // false at the start of a menu and immediately after a separator. bool mbSeparatorAllowed; // false at the start of a menu and immediately after a separator.
TranslatableString mCurrentMenuName; TranslatableString mCurrentMenuName;
TranslatableString mNiceName;
int mLastProcessId;
std::unique_ptr<wxMenu> uCurrentMenu; std::unique_ptr<wxMenu> uCurrentMenu;
wxMenu *mCurrentMenu {}; wxMenu *mCurrentMenu {};

View File

@ -672,6 +672,7 @@ struct Handler : CommandHandlerObject {
void OnContrast(const CommandContext &context) void OnContrast(const CommandContext &context)
{ {
auto &project = context.project; auto &project = context.project;
CommandManager::Get(project).RegisterLastAnalyzer(context); //Register Contrast as Last Analyzer
auto contrastDialog = auto contrastDialog =
&project.AttachedWindows::Get< ContrastDialog >( sContrastDialogKey ); &project.AttachedWindows::Get< ContrastDialog >( sContrastDialogKey );

View File

@ -100,6 +100,7 @@ Effect::Effect()
mUIParent = NULL; mUIParent = NULL;
mUIDialog = NULL; mUIDialog = NULL;
mUIFlags = 0;
mNumAudioIn = 0; mNumAudioIn = 0;
mNumAudioOut = 0; mNumAudioOut = 0;
@ -1179,6 +1180,14 @@ wxString Effect::HelpPage()
return wxEmptyString; return wxEmptyString;
} }
void Effect::SetUIFlags(unsigned flags) {
mUIFlags = flags;
}
unsigned Effect::TestUIFlags(unsigned mask) {
return mask & mUIFlags;
}
bool Effect::IsBatchProcessing() bool Effect::IsBatchProcessing()
{ {
return mIsBatch; return mIsBatch;

View File

@ -244,6 +244,8 @@ class AUDACITY_DLL_API Effect /* not final */ : public wxEvtHandler,
// Fully qualified local help file name // Fully qualified local help file name
virtual wxString HelpPage(); virtual wxString HelpPage();
virtual void SetUIFlags(unsigned flags);
virtual unsigned TestUIFlags(unsigned mask);
virtual bool IsBatchProcessing(); virtual bool IsBatchProcessing();
virtual void SetBatchProcessing(bool start); virtual void SetBatchProcessing(bool start);
@ -476,6 +478,7 @@ protected:
wxDialog *mUIDialog; wxDialog *mUIDialog;
wxWindow *mUIParent; wxWindow *mUIParent;
int mUIResultID; int mUIResultID;
unsigned mUIFlags;
sampleCount mSampleCnt; sampleCount mSampleCnt;

View File

@ -54,11 +54,13 @@ public:
// Flag used to disable prompting for configuration parameteres. // Flag used to disable prompting for configuration parameteres.
kConfigured = 0x01, kConfigured = 0x01,
// Flag used to disable saving the state after processing. // Flag used to disable saving the state after processing.
kSkipState = 0x02, kSkipState = 0x02,
// Flag used to disable "Repeat Last Effect" // Flag used to disable "Repeat Last Effect"
kDontRepeatLast = 0x04, kDontRepeatLast = 0x04,
// Flag used to disable "Select All during Repeat Generator Effect" // Flag used to disable "Select All during Repeat Generator Effect"
kRepeatGen = 0x08, kRepeatGen = 0x08,
// Flag used for repeating Nyquist Prompt
kRepeatNyquistPrompt = 0x10,
}; };
/** Get the singleton instance of the EffectManager. Probably not safe /** Get the singleton instance of the EffectManager. Probably not safe

View File

@ -1925,6 +1925,7 @@ wxDialog *EffectUI::DialogFactory( wxWindow &parent, EffectHostInterface *pHost,
EffectRack::Get( context.project ).Add(effect); EffectRack::Get( context.project ).Add(effect);
} }
#endif #endif
effect->SetUIFlags(flags);
success = effect->DoEffect( success = effect->DoEffect(
rate, rate,
&tracks, &tracks,
@ -1959,23 +1960,32 @@ wxDialog *EffectUI::DialogFactory( wxWindow &parent, EffectHostInterface *pHost,
/* i18n-hint: %s will be the name of the effect which will be /* i18n-hint: %s will be the name of the effect which will be
* repeated if this menu item is chosen */ * repeated if this menu item is chosen */
auto lastEffectDesc = XO("Repeat %s").Format(shortDesc); auto lastEffectDesc = XO("Repeat %s").Format(shortDesc);
auto& menuManager = MenuManager::Get(project);
switch ( type ) { switch ( type ) {
case EffectTypeGenerate: case EffectTypeGenerate:
commandManager.Modify(wxT("RepeatLastGenerator"), lastEffectDesc); commandManager.Modify(wxT("RepeatLastGenerator"), lastEffectDesc);
MenuManager::Get(project).mLastGenerator = ID; menuManager.mLastGenerator = ID;
menuManager.mRepeatGeneratorFlags = EffectManager::kConfigured;
break; break;
case EffectTypeProcess: case EffectTypeProcess:
commandManager.Modify(wxT("RepeatLastEffect"), lastEffectDesc); commandManager.Modify(wxT("RepeatLastEffect"), lastEffectDesc);
MenuManager::Get(project).mLastEffect = ID; menuManager.mLastEffect = ID;
menuManager.mRepeatEffectFlags = EffectManager::kConfigured;
break; break;
case EffectTypeAnalyze: case EffectTypeAnalyze:
commandManager.Modify(wxT("RepeatLastAnalyzer"), lastEffectDesc); commandManager.Modify(wxT("RepeatLastAnalyzer"), lastEffectDesc);
MenuManager::Get(project).mLastAnalyzer = ID; menuManager.mLastAnalyzer = ID;
menuManager.mLastAnalyzerRegistration = MenuCreator::repeattypeplugin;
menuManager.mRepeatAnalyzerFlags = EffectManager::kConfigured;
break; break;
case EffectTypeTool: case EffectTypeTool:
commandManager.Modify(wxT("RepeatLastTool"), lastEffectDesc); commandManager.Modify(wxT("RepeatLastTool"), lastEffectDesc);
MenuManager::Get(project).mLastTool = ID; menuManager.mLastTool = ID;
MenuManager::Get(project).mLastToolIsMacro = false; menuManager.mLastToolRegistration = MenuCreator::repeattypeplugin;
menuManager.mRepeatToolFlags = EffectManager::kConfigured;
if (shortDesc == XO("Nyquist Prompt")) {
menuManager.mRepeatToolFlags = EffectManager::kRepeatNyquistPrompt; //Nyquist Prompt is not configured
}
break; break;
} }
} }

View File

@ -1001,8 +1001,12 @@ finish:
bool NyquistEffect::ShowInterface( bool NyquistEffect::ShowInterface(
wxWindow &parent, const EffectDialogFactory &factory, bool forceModal) wxWindow &parent, const EffectDialogFactory &factory, bool forceModal)
{ {
// Show the normal (prompt or effect) interface bool res = true;
bool res = Effect::ShowInterface(parent, factory, forceModal); if (!(Effect::TestUIFlags(EffectManager::kRepeatNyquistPrompt) && mIsPrompt)) {
// Show the normal (prompt or effect) interface
res = Effect::ShowInterface(parent, factory, forceModal);
}
// Remember if the user clicked debug // Remember if the user clicked debug
mDebug = (mUIResultID == eDebugID); mDebug = (mUIResultID == eDebugID);

View File

@ -377,6 +377,14 @@ struct Handler : CommandHandlerObject {
void OnResetConfig(const CommandContext &context) void OnResetConfig(const CommandContext &context)
{ {
auto &project = context.project; auto &project = context.project;
auto &menuManager = MenuManager::Get(project);
menuManager.mLastAnalyzerRegistration = MenuCreator::repeattypenone;
menuManager.mLastToolRegistration = MenuCreator::repeattypenone;
menuManager.mLastGenerator = "";
menuManager.mLastEffect = "";
menuManager.mLastAnalyzer = "";
menuManager.mLastTool = "";
gPrefs->DeleteAll(); gPrefs->DeleteAll();
// Directory will be reset on next restart. // Directory will be reset on next restart.
@ -429,46 +437,72 @@ void OnManageEffects(const CommandContext &context)
DoManagePluginsMenu(project, EffectTypeProcess); DoManagePluginsMenu(project, EffectTypeProcess);
} }
void OnAnalyzer2(wxCommandEvent& evt) { return; }
void OnRepeatLastGenerator(const CommandContext &context) void OnRepeatLastGenerator(const CommandContext &context)
{ {
auto lastEffect = MenuManager::Get(context.project).mLastGenerator; auto& menuManager = MenuManager::Get(context.project);
auto lastEffect = menuManager.mLastGenerator;
if (!lastEffect.empty()) if (!lastEffect.empty())
{ {
EffectUI::DoEffect( EffectUI::DoEffect(
lastEffect, context, EffectManager::kConfigured | EffectManager::kRepeatGen); lastEffect, context, menuManager.mRepeatGeneratorFlags | EffectManager::kRepeatGen);
} }
} }
void OnRepeatLastEffect(const CommandContext &context) void OnRepeatLastEffect(const CommandContext &context)
{ {
auto lastEffect = MenuManager::Get(context.project).mLastEffect; auto& menuManager = MenuManager::Get(context.project);
auto lastEffect = menuManager.mLastEffect;
if (!lastEffect.empty()) if (!lastEffect.empty())
{ {
EffectUI::DoEffect( EffectUI::DoEffect(
lastEffect, context, EffectManager::kConfigured); lastEffect, context, menuManager.mRepeatGeneratorFlags);
} }
} }
void OnRepeatLastAnalyzer(const CommandContext &context) void OnRepeatLastAnalyzer(const CommandContext& context)
{ {
auto lastEffect = MenuManager::Get(context.project).mLastAnalyzer; auto& menuManager = MenuManager::Get(context.project);
if (!lastEffect.empty()) switch (menuManager.mLastAnalyzerRegistration) {
{ case MenuCreator::repeattypeplugin:
EffectUI::DoEffect( {
lastEffect, context, EffectManager::kConfigured); auto lastEffect = menuManager.mLastAnalyzer;
} if (!lastEffect.empty())
} {
void OnRepeatLastTool(const CommandContext &context)
{
auto lastEffect = MenuManager::Get(context.project).mLastTool;
if (!lastEffect.empty())
{
if (!MenuManager::Get(context.project).mLastToolIsMacro)
EffectUI::DoEffect( EffectUI::DoEffect(
lastEffect, context, EffectManager::kConfigured); lastEffect, context, menuManager.mRepeatAnalyzerFlags);
else }
OnApplyMacroDirectlyByName(context, lastEffect); }
break;
case MenuCreator::repeattypeunique:
CommandManager::Get(context.project).DoRepeatProcess(context,
menuManager.mLastAnalyzerRegisteredId);
break;
}
}
void OnRepeatLastTool(const CommandContext& context)
{
auto& menuManager = MenuManager::Get(context.project);
switch (menuManager.mLastToolRegistration) {
case MenuCreator::repeattypeplugin:
{
auto lastEffect = menuManager.mLastTool;
if (!lastEffect.empty())
{
EffectUI::DoEffect(
lastEffect, context, menuManager.mRepeatToolFlags);
}
}
break;
case MenuCreator::repeattypeunique:
CommandManager::Get(context.project).DoRepeatProcess(context,
menuManager.mLastToolRegisteredId);
break;
case MenuCreator::repeattypeapplymacro:
OnApplyMacroDirectlyByName(context, menuManager.mLastTool);
break;
} }
} }
@ -488,6 +522,7 @@ void OnManageTools(const CommandContext &context )
void OnManageMacros(const CommandContext &context ) void OnManageMacros(const CommandContext &context )
{ {
auto &project = context.project; auto &project = context.project;
CommandManager::Get(project).RegisterLastTool(context); //Register Macros as Last Tool
auto macrosWindow = auto macrosWindow =
&project.AttachedWindows::Get< MacrosWindow >( sMacrosWindowKey ); &project.AttachedWindows::Get< MacrosWindow >( sMacrosWindowKey );
if (macrosWindow) { if (macrosWindow) {
@ -500,6 +535,7 @@ void OnManageMacros(const CommandContext &context )
void OnApplyMacrosPalette(const CommandContext &context ) void OnApplyMacrosPalette(const CommandContext &context )
{ {
auto &project = context.project; auto &project = context.project;
CommandManager::Get(project).RegisterLastTool(context); //Register Palette as Last Tool
auto macrosWindow = auto macrosWindow =
&project.AttachedWindows::Get< MacrosWindow >( sMacrosWindowKey ); &project.AttachedWindows::Get< MacrosWindow >( sMacrosWindowKey );
if (macrosWindow) { if (macrosWindow) {
@ -511,12 +547,14 @@ void OnApplyMacrosPalette(const CommandContext &context )
void OnScreenshot(const CommandContext &context ) void OnScreenshot(const CommandContext &context )
{ {
CommandManager::Get(context.project).RegisterLastTool(context); //Register Screenshot as Last Tool
::OpenScreenshotTools( context.project ); ::OpenScreenshotTools( context.project );
} }
void OnBenchmark(const CommandContext &context) void OnBenchmark(const CommandContext &context)
{ {
auto &project = context.project; auto &project = context.project;
CommandManager::Get(project).RegisterLastTool(context); //Register Run Benchmark as Last Tool
auto &window = GetProjectFrame( project ); auto &window = GetProjectFrame( project );
::RunBenchmark( &window, project); ::RunBenchmark( &window, project);
} }
@ -570,19 +608,20 @@ void OnApplyMacroDirectlyByName(const CommandContext& context, const MacroID& Na
* repeated if this menu item is chosen */ * repeated if this menu item is chosen */
MenuManager::ModifyUndoMenuItems( project ); MenuManager::ModifyUndoMenuItems( project );
TranslatableString desc; TranslatableString desc;
EffectManager& em = EffectManager::Get(); EffectManager& em = EffectManager::Get();
auto shortDesc = em.GetCommandName(Name); auto shortDesc = em.GetCommandName(Name);
auto& undoManager = UndoManager::Get(project); auto& undoManager = UndoManager::Get(project);
auto& commandManager = CommandManager::Get(project); auto& commandManager = CommandManager::Get(project);
int cur = undoManager.GetCurrentState(); int cur = undoManager.GetCurrentState();
if (undoManager.UndoAvailable()) { if (undoManager.UndoAvailable()) {
undoManager.GetShortDescription(cur, &desc); undoManager.GetShortDescription(cur, &desc);
commandManager.Modify(wxT("RepeatLastTool"), XXO("&Repeat %s") commandManager.Modify(wxT("RepeatLastTool"), XXO("&Repeat %s")
.Format(desc)); .Format(desc));
MenuManager::Get(project).mLastTool = Name; auto& menuManager = MenuManager::Get(project);
MenuManager::Get(project).mLastToolIsMacro = true; menuManager.mLastTool = Name;
} menuManager.mLastToolRegistration = MenuCreator::repeattypeapplymacro;
}
} }