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&
HasLastAnalyzerFlag() { static ReservedCommandFlag flag{
[](const AudacityProject &project) {
if (MenuManager::Get(project).mLastAnalyzerRegistration == MenuCreator::repeattypeunique) return true;
return !MenuManager::Get(project).mLastAnalyzer.empty();
}
}; return flag;
@ -260,7 +261,9 @@ const ReservedCommandFlag&
const ReservedCommandFlag&
HasLastToolFlag() { static ReservedCommandFlag flag{
[](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;
}

View File

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

View File

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

View File

@ -52,8 +52,21 @@ public:
PluginID mLastGenerator{};
PluginID mLastEffect{};
PluginID mLastAnalyzer{};
int mLastAnalyzerRegistration;
int mLastAnalyzerRegisteredId;
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;

View File

@ -235,6 +235,7 @@ CommandManager::CommandManager():
{
mbSeparatorAllowed = false;
SetMaxList();
mLastProcessId = 0;
}
///
@ -722,23 +723,6 @@ CommandListEntry *CommandManager::NewIdentifier(const CommandID & nameIn,
entry->id = wxID_EXIT;
else if (name == wxT("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
entry->name = name;
@ -1192,6 +1176,7 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent &
return false;
}
/// HandleCommandEntry() takes a CommandListEntry and executes it
/// returning true iff successful. If you pass any flags,
///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.
if (!allowed)
return true;
mNiceName = NiceName;
}
else {
mNiceName = XO("");
}
const CommandContext context{ project, evt, entry->index, entry->parameter };
auto &handler = entry->finder(project);
(handler.*(entry->callback))(context);
mLastProcessId = 0;
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.
///If it matches a command, it will call the appropriate
///CommandManagerListener function. If you pass any flags,
@ -1236,6 +1260,7 @@ bool CommandManager::HandleCommandEntry(AudacityProject &project,
bool CommandManager::HandleMenuID(
AudacityProject &project, int id, CommandFlag flags, bool alwaysEnabled)
{
mLastProcessId = id;
CommandListEntry *entry = mCommandNumericIDHash[id];
auto hook = sMenuHook();

View File

@ -209,6 +209,9 @@ class AUDACITY_DLL_API CommandManager final
// Lyrics and MixerTrackCluster classes use it.
bool FilterKeyEvent(AudacityProject *project, const wxKeyEvent & evt, bool permit = false);
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 {
CommandFailure,
@ -356,6 +359,8 @@ private:
bool mbSeparatorAllowed; // false at the start of a menu and immediately after a separator.
TranslatableString mCurrentMenuName;
TranslatableString mNiceName;
int mLastProcessId;
std::unique_ptr<wxMenu> uCurrentMenu;
wxMenu *mCurrentMenu {};

View File

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

View File

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

View File

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

View File

@ -54,11 +54,13 @@ public:
// Flag used to disable prompting for configuration parameteres.
kConfigured = 0x01,
// Flag used to disable saving the state after processing.
kSkipState = 0x02,
kSkipState = 0x02,
// Flag used to disable "Repeat Last Effect"
kDontRepeatLast = 0x04,
// Flag used to disable "Select All during Repeat Generator Effect"
kRepeatGen = 0x08,
// Flag used for repeating Nyquist Prompt
kRepeatNyquistPrompt = 0x10,
};
/** 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);
}
#endif
effect->SetUIFlags(flags);
success = effect->DoEffect(
rate,
&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
* repeated if this menu item is chosen */
auto lastEffectDesc = XO("Repeat %s").Format(shortDesc);
auto& menuManager = MenuManager::Get(project);
switch ( type ) {
case EffectTypeGenerate:
commandManager.Modify(wxT("RepeatLastGenerator"), lastEffectDesc);
MenuManager::Get(project).mLastGenerator = ID;
menuManager.mLastGenerator = ID;
menuManager.mRepeatGeneratorFlags = EffectManager::kConfigured;
break;
case EffectTypeProcess:
commandManager.Modify(wxT("RepeatLastEffect"), lastEffectDesc);
MenuManager::Get(project).mLastEffect = ID;
menuManager.mLastEffect = ID;
menuManager.mRepeatEffectFlags = EffectManager::kConfigured;
break;
case EffectTypeAnalyze:
commandManager.Modify(wxT("RepeatLastAnalyzer"), lastEffectDesc);
MenuManager::Get(project).mLastAnalyzer = ID;
menuManager.mLastAnalyzer = ID;
menuManager.mLastAnalyzerRegistration = MenuCreator::repeattypeplugin;
menuManager.mRepeatAnalyzerFlags = EffectManager::kConfigured;
break;
case EffectTypeTool:
commandManager.Modify(wxT("RepeatLastTool"), lastEffectDesc);
MenuManager::Get(project).mLastTool = ID;
MenuManager::Get(project).mLastToolIsMacro = false;
menuManager.mLastTool = ID;
menuManager.mLastToolRegistration = MenuCreator::repeattypeplugin;
menuManager.mRepeatToolFlags = EffectManager::kConfigured;
if (shortDesc == XO("Nyquist Prompt")) {
menuManager.mRepeatToolFlags = EffectManager::kRepeatNyquistPrompt; //Nyquist Prompt is not configured
}
break;
}
}

View File

@ -1001,8 +1001,12 @@ finish:
bool NyquistEffect::ShowInterface(
wxWindow &parent, const EffectDialogFactory &factory, bool forceModal)
{
// Show the normal (prompt or effect) interface
bool res = Effect::ShowInterface(parent, factory, forceModal);
bool res = true;
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
mDebug = (mUIResultID == eDebugID);

View File

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