From 87a9f34c2253d6a3c204d519d761872289ac010f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 11 May 2019 18:49:02 -0400 Subject: [PATCH] ScreenshotCommand uses hooks in AudacityCommand and Effect dialogs... ... so that they don't have a static linkage dependency on it, and that frees it from dependency cycles, to a high level --- src/commands/AudacityCommand.cpp | 24 +++++++++++++++++++++--- src/commands/AudacityCommand.h | 5 +++++ src/commands/ScreenshotCommand.cpp | 17 ++++++++++++++++- src/commands/ScreenshotCommand.h | 2 +- src/effects/Effect.cpp | 25 ++++++++++++++++++++++--- src/effects/Effect.h | 5 +++++ 6 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/commands/AudacityCommand.cpp b/src/commands/AudacityCommand.cpp index c3f3b2c03..7ed08d232 100644 --- a/src/commands/AudacityCommand.cpp +++ b/src/commands/AudacityCommand.cpp @@ -44,10 +44,27 @@ ShuttleGui. #include "../widgets/HelpSystem.h" #include "../widgets/ErrorDialog.h" -#include "../commands/ScreenshotCommand.h" - #include +namespace { + +AudacityCommand::VetoDialogHook &GetVetoDialogHook() +{ + static AudacityCommand::VetoDialogHook sHook = nullptr; + return sHook; +} + +} + +auto AudacityCommand::SetVetoDialogHook( VetoDialogHook hook ) + -> VetoDialogHook +{ + auto &theHook = GetVetoDialogHook(); + auto result = theHook; + theHook = hook; + return result; +} + AudacityCommand::AudacityCommand() { mProgress = NULL; @@ -105,7 +122,8 @@ bool AudacityCommand::ShowInterface(wxWindow *parent, bool WXUNUSED(forceModal)) mUIDialog->SetMinSize(mUIDialog->GetSize()); // The Screenshot command might be popping this dialog up, just to capture it. - if( ScreenshotCommand::MayCapture( mUIDialog ) ) + auto hook = GetVetoDialogHook(); + if( hook && hook( mUIDialog ) ) return false; bool res = mUIDialog->ShowModal() != 0; diff --git a/src/commands/AudacityCommand.h b/src/commands/AudacityCommand.h index c17d15dad..d454c337d 100644 --- a/src/commands/AudacityCommand.h +++ b/src/commands/AudacityCommand.h @@ -45,6 +45,11 @@ class AUDACITY_DLL_API AudacityCommand /* not final */ : public wxEvtHandler, public: AudacityCommand(); virtual ~AudacityCommand(); + + // Type of a registered function that, if it returns true, + // causes ShowInterface to return early without making any dialog + using VetoDialogHook = bool (*) ( wxDialog* ); + static VetoDialogHook SetVetoDialogHook( VetoDialogHook hook ); // ComponentInterface implementation diff --git a/src/commands/ScreenshotCommand.cpp b/src/commands/ScreenshotCommand.cpp index bb9872599..24be56367 100644 --- a/src/commands/ScreenshotCommand.cpp +++ b/src/commands/ScreenshotCommand.cpp @@ -20,6 +20,8 @@ small calculations of rectangles. #include "../Audacity.h" #include "ScreenshotCommand.h" +#include + #include "../Project.h" #include #include @@ -31,6 +33,7 @@ small calculations of rectangles. #include "../AdornedRulerPanel.h" #include "../TrackPanel.h" +#include "../effects/Effect.h" #include "../toolbars/ToolManager.h" #include "../Prefs.h" #include "../Shuttle.h" @@ -87,7 +90,19 @@ kBackgroundStrings[ ScreenshotCommand::nBackgrounds ] = }; -bool ScreenshotCommand::DefineParams( ShuttleParams & S ){ +ScreenshotCommand::ScreenshotCommand() +{ + mbBringToTop=true; + mIgnore=NULL; + + static std::once_flag flag; + std::call_once( flag, []{ + AudacityCommand::SetVetoDialogHook( MayCapture ); + Effect::SetVetoDialogHook( MayCapture ); + }); +} + +bool ScreenshotCommand::DefineParams( ShuttleParams & S ){ S.Define( mPath, wxT("Path"), wxT("")); S.DefineEnum( mWhat, wxT("CaptureWhat"), kwindow,kCaptureWhatStrings, nCaptureWhats ); S.DefineEnum( mBack, wxT("Background"), kNone, kBackgroundStrings, nBackgrounds ); diff --git a/src/commands/ScreenshotCommand.h b/src/commands/ScreenshotCommand.h index f7e1a82ce..f2ff701d9 100644 --- a/src/commands/ScreenshotCommand.h +++ b/src/commands/ScreenshotCommand.h @@ -78,7 +78,7 @@ public: nCaptureWhats }; - ScreenshotCommand(){ mbBringToTop=true;mIgnore=NULL;}; + ScreenshotCommand(); // ComponentInterface overrides ComponentInterfaceSymbol GetSymbol() override {return SCREENSHOT_PLUGIN_SYMBOL;}; wxString GetDescription() override {return _("Takes screenshots.");}; diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index b20ad3ed9..7d70cf45b 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -59,6 +59,7 @@ greater use in future. #include "../ShuttleGui.h" #include "../Shuttle.h" #include "../WaveTrack.h" +#include "../commands/Command.h" #include "../toolbars/ControlToolBar.h" #include "../widgets/AButton.h" #include "../widgets/ProgressDialog.h" @@ -76,8 +77,6 @@ greater use in future. #include #endif -#include "../commands/ScreenshotCommand.h" - #include // Effect application counter @@ -109,6 +108,25 @@ const wxString Effect::kFactoryDefaultsIdent = wxT(""); using t2bHash = std::unordered_map< void*, bool >; +namespace { + +Effect::VetoDialogHook &GetVetoDialogHook() +{ + static Effect::VetoDialogHook sHook = nullptr; + return sHook; +} + +} + +auto Effect::SetVetoDialogHook( VetoDialogHook hook ) + -> VetoDialogHook +{ + auto &theHook = GetVetoDialogHook(); + auto result = theHook; + theHook = hook; + return result; +} + Effect::Effect() { mClient = NULL; @@ -556,7 +574,8 @@ bool Effect::ShowInterface(wxWindow *parent, bool forceModal) mUIDialog->Fit(); mUIDialog->SetMinSize(mUIDialog->GetSize()); - if( ScreenshotCommand::MayCapture( mUIDialog ) ) + auto hook = GetVetoDialogHook(); + if( hook && hook( mUIDialog ) ) return false; if( SupportsRealtime() && !forceModal ) diff --git a/src/effects/Effect.h b/src/effects/Effect.h index 2f41d3274..5bffba41c 100644 --- a/src/effects/Effect.h +++ b/src/effects/Effect.h @@ -72,6 +72,11 @@ class AUDACITY_DLL_API Effect /* not final */ : public wxEvtHandler, Effect(); virtual ~Effect(); + // Type of a registered function that, if it returns true, + // causes ShowInterface to return early without making any dialog + using VetoDialogHook = bool (*) ( wxDialog* ); + static VetoDialogHook SetVetoDialogHook( VetoDialogHook hook ); + // ComponentInterface implementation PluginPath GetPath() override;