1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-02 00:29:41 +02:00

Break dependency cycles related to Commands

This commit is contained in:
Paul Licameli 2019-05-18 20:31:49 -04:00
commit c401a54469
32 changed files with 234 additions and 158 deletions

View File

@ -95,7 +95,7 @@ class ScreenFrame final : public wxFrame
wxStatusBar *mStatus;
std::unique_ptr<ScreenshotCommand> mCommand;
CommandContext mContext;
const CommandContext mContext;
DECLARE_EVENT_TABLE()
};
@ -469,7 +469,7 @@ void ScreenFrame::PopulateOrExchange(ShuttleGui & S)
CentreOnParent();
}
SetIcon(mContext.GetProject()->GetIcon());
SetIcon(mContext.project.GetIcon());
}
bool ScreenFrame::ProcessEvent(wxEvent & e)
@ -564,8 +564,8 @@ void ScreenFrame::SizeMainWindow(int w, int h)
{
int top = 20;
mContext.GetProject()->Maximize(false);
mContext.GetProject()->SetSize(16, 16 + top, w, h);
mContext.project.Maximize(false);
mContext.project.SetSize(16, 16 + top, w, h);
//Bug383 - Toolbar Resets not wanted.
//mContext.GetProject()->GetToolManager()->Reset();
}
@ -669,9 +669,9 @@ void ScreenFrame::OnCaptureSomething(wxCommandEvent & event)
void ScreenFrame::TimeZoom(double seconds)
{
int width, height;
mContext.GetProject()->GetClientSize(&width, &height);
mContext.GetProject()->mViewInfo.SetZoom((0.75 * width) / seconds);
mContext.GetProject()->RedrawProject();
mContext.project.GetClientSize(&width, &height);
mContext.project.mViewInfo.SetZoom((0.75 * width) / seconds);
mContext.project.RedrawProject();
}
void ScreenFrame::OnOneSec(wxCommandEvent & WXUNUSED(event))
@ -708,7 +708,7 @@ void ScreenFrame::SizeTracks(int h)
// If there should be more-than-stereo tracks, this makes
// each channel as high as for a stereo channel
auto tracks = mContext.GetProject()->GetTracks();
auto tracks = mContext.project.GetTracks();
for (auto t : tracks->Leaders<WaveTrack>()) {
auto channels = TrackList::Channels(t);
auto nChannels = channels.size();
@ -716,15 +716,15 @@ void ScreenFrame::SizeTracks(int h)
for (auto channel : channels)
channel->SetHeight(height);
}
mContext.GetProject()->RedrawProject();
mContext.project.RedrawProject();
}
void ScreenFrame::OnShortTracks(wxCommandEvent & WXUNUSED(event))
{
for (auto t : mContext.GetProject()->GetTracks()->Any<WaveTrack>())
for (auto t : mContext.project.GetTracks()->Any<WaveTrack>())
t->SetHeight(t->GetMinimizedHeight());
mContext.GetProject()->RedrawProject();
mContext.project.RedrawProject();
}
void ScreenFrame::OnMedTracks(wxCommandEvent & WXUNUSED(event))

View File

@ -37,17 +37,33 @@ ShuttleGui.
#include "audacity/ConfigInterface.h"
#include "../Project.h"
#include "../Shuttle.h"
#include "../ShuttleGui.h"
#include "../widgets/ProgressDialog.h"
#include "../widgets/HelpSystem.h"
#include "../widgets/ErrorDialog.h"
#include "../commands/ScreenshotCommand.h"
#include <unordered_map>
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;
@ -70,12 +86,6 @@ VendorSymbol AudacityCommand::GetVendor(){ return XO("Audacity");}
wxString AudacityCommand::GetVersion(){ return AUDACITY_VERSION_STRING;}
bool AudacityCommand::Apply() {
AudacityProject * pProj = GetActiveProject();
const CommandContext context( *pProj );
return Apply( context );
};
bool AudacityCommand::Init(){
if( !mNeedsInit )
return true;
@ -105,7 +115,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;

View File

@ -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
@ -64,8 +69,7 @@ class AUDACITY_DLL_API AudacityCommand /* not final */ : public wxEvtHandler,
virtual bool IsBatchProcessing(){ return mIsBatch;}
virtual void SetBatchProcessing(bool start){ mIsBatch = start;};
virtual bool Apply(const CommandContext & WXUNUSED(context) ) {return false;};
virtual bool Apply(); // redirects to the command context version.
virtual bool Apply(const CommandContext & WXUNUSED(context) ) {return false;};
bool ShowInterface(wxWindow *parent, bool forceModal = false);
virtual void SetHostUI(EffectUIHostInterface * WXUNUSED(host)){;};

View File

@ -17,6 +17,12 @@
#include "BatchEvalCommand.h"
#include "CommandContext.h"
#include "CommandDirectory.h"
#include "../Project.h"
static CommandDirectory::RegisterType sRegisterType{
std::make_unique<BatchEvalCommandType>()
};
ComponentInterfaceSymbol BatchEvalCommandType::BuildName()
{
@ -35,7 +41,7 @@ void BatchEvalCommandType::BuildSignature(CommandSignature &signature)
OldStyleCommandPointer BatchEvalCommandType::Create(std::unique_ptr<CommandOutputTargets> && WXUNUSED(target))
{
return std::make_shared<BatchEvalCommand>(*this);
return std::make_shared<BatchEvalCommand>(*GetActiveProject(), *this);
}
bool BatchEvalCommand::Apply(const CommandContext & context)

View File

@ -26,6 +26,8 @@ to that system.
#include "CommandType.h"
#include "../BatchCommands.h"
class AudacityProject;
class BatchEvalCommandType final : public OldStyleCommandType
{
public:
@ -37,8 +39,8 @@ public:
class BatchEvalCommand final : public CommandImplementation
{
public:
BatchEvalCommand(OldStyleCommandType &type)
: CommandImplementation(type)
BatchEvalCommand(AudacityProject &project, OldStyleCommandType &type)
: CommandImplementation(project, type)
{ }
virtual ~BatchEvalCommand();

View File

@ -79,16 +79,17 @@ classes derived from it.
#include "Command.h"
#include <map>
#include <wx/log.h>
#include <wx/string.h>
#include <wx/variant.h>
#include <wx/arrstr.h>
#include "CommandBuilder.h"
#include "CommandTargets.h"
#include "CommandDirectory.h"
#include "CommandContext.h"
#include "../Project.h"
#include "../AudacityException.h"
@ -119,9 +120,10 @@ bool DecoratedCommand::SetParameter(const wxString &paramName,
return mCommand->SetParameter(paramName, paramValue);
}
ApplyAndSendResponse::ApplyAndSendResponse(const OldStyleCommandPointer &cmd, std::unique_ptr<CommandOutputTargets> &target)
ApplyAndSendResponse::ApplyAndSendResponse(
const OldStyleCommandPointer &cmd, std::unique_ptr<CommandOutputTargets> &target)
: DecoratedCommand(cmd),
mCtx( std::make_unique<CommandContext>( *GetActiveProject(), std::move(target) ) )
mCtx( std::make_unique<CommandContext>( cmd->mProject, std::move(target) ) )
{
}
@ -167,8 +169,10 @@ bool ApplyAndSendResponse::Apply()
return result;
}
CommandImplementation::CommandImplementation(OldStyleCommandType &type)
: mType(type),
CommandImplementation::CommandImplementation(
AudacityProject &project, OldStyleCommandType &type)
: OldStyleCommand{ project },
mType(type),
mParams(type.GetSignature().GetDefaults()),
mSetParams()
{
@ -257,7 +261,7 @@ CommandSignature &CommandImplementation::GetSignature()
bool CommandImplementation::SetParameter(const wxString &paramName, const wxVariant &paramValue)
{
wxASSERT(!paramValue.IsType(wxT("null")));
CommandContext context( * GetActiveProject());
CommandContext context( mProject );
ParamValueMap::iterator iter = mParams.find(paramName);
if (iter == mParams.end())
{

View File

@ -28,7 +28,9 @@ class CommandOutputTargets;
class OldStyleCommand /* not final */
{
public:
OldStyleCommand() {};
AudacityProject &mProject;
OldStyleCommand(AudacityProject &project) : mProject{ project } {};
virtual ~OldStyleCommand() { }
virtual ComponentInterfaceSymbol GetSymbol() = 0;
virtual CommandSignature &GetSignature() = 0;
@ -47,7 +49,7 @@ protected:
OldStyleCommandPointer mCommand;
public:
DecoratedCommand(const OldStyleCommandPointer &cmd)
: mCommand(cmd)
: OldStyleCommand{ cmd->mProject }, mCommand(cmd)
{
wxASSERT(cmd != NULL);
}
@ -62,10 +64,11 @@ public:
class ApplyAndSendResponse : public DecoratedCommand
{
public:
ApplyAndSendResponse(const OldStyleCommandPointer &cmd, std::unique_ptr<CommandOutputTargets> &target);
ApplyAndSendResponse(
const OldStyleCommandPointer &cmd, std::unique_ptr<CommandOutputTargets> &target);
bool Apply() override;
bool Apply(const CommandContext &context) override;// Error to use this.
std::unique_ptr<CommandContext> mCtx;
std::unique_ptr<const CommandContext> mCtx;
};
@ -95,7 +98,7 @@ protected:
public:
/// Constructor should not be called directly; only by a factory which
/// ensures name and params are set appropriately for the command.
CommandImplementation(OldStyleCommandType &type);
CommandImplementation(AudacityProject &project, OldStyleCommandType &type);
virtual ~CommandImplementation();

View File

@ -25,7 +25,7 @@ system by constructing BatchCommandEval objects.
#include "CommandBuilder.h"
#include "CommandDirectory.h"
#include "BatchEvalCommand.h"
#include "Command.h"
#include "ScriptCommandRelay.h"
#include "CommandContext.h"
#include "CommandTargets.h"

View File

@ -24,15 +24,13 @@ messaging from a command back to its invoker.
#include "CommandContext.h"
#include <map>
#include <wx/app.h>
#include <wx/log.h>
#include <wx/string.h>
#include <wx/variant.h>
#include <wx/arrstr.h>
#include "CommandBuilder.h"
#include "CommandTargets.h"
#include "CommandDirectory.h"
#include "../Project.h"
CommandContext::CommandContext(
AudacityProject &p
@ -92,9 +90,6 @@ void CommandContext::Progress( double d ) const
AudacityApp * CommandContext::GetApp() const
{ return (AudacityApp *) wxTheApp;}
AudacityProject *CommandContext::GetProject() const
{ return GetActiveProject();}
void CommandContext::StartArray() const
{
if( pOutput )

View File

@ -11,8 +11,8 @@
#ifndef __AUDACITY_COMMAND_CONTEXT__
#define __AUDACITY_COMMAND_CONTEXT__
#include <memory>
#include "audacity/Types.h"
#include "Command.h"
class AudacityProject;
class AudacityApp;
@ -56,6 +56,5 @@ public:
int index;
CommandParameter parameter;
AudacityApp *GetApp() const;
AudacityProject *GetProject() const;
};
#endif

View File

@ -17,10 +17,6 @@ functions to look up a command by name.
#include "../Audacity.h"
#include "CommandDirectory.h"
#include "HelpCommand.h"
#include "MessageCommand.h"
#include "BatchEvalCommand.h"
std::unique_ptr<CommandDirectory> CommandDirectory::mInstance;
CommandDirectory::CommandDirectory()
@ -28,7 +24,8 @@ CommandDirectory::CommandDirectory()
// Create the command map.
// First we have commands which return information
//AddCommand(std::make_unique<MessageCommandType>());
AddCommand(std::make_unique<BatchEvalCommandType>());
// AddCommand(std::make_unique<BatchEvalCommandType>());
// Legacy adapter commands that previously was needed to
@ -68,24 +65,30 @@ CommandDirectory::~CommandDirectory()
OldStyleCommandType *CommandDirectory::LookUp(const wxString &cmdName) const
{
CommandMap::const_iterator iter = mCmdMap.find(cmdName);
if (iter == mCmdMap.end())
auto iter = sCmdMap().find(cmdName);
if (iter == sCmdMap().end())
{
return NULL;
return nullptr;
}
return iter->second.get();
}
void CommandDirectory::AddCommand(std::unique_ptr<OldStyleCommandType> &&type)
CommandMap &CommandDirectory::sCmdMap()
{
static CommandMap theMap;
return theMap;
}
void CommandDirectory::AddCommand(std::unique_ptr<OldStyleCommandType> type)
{
wxASSERT(type != NULL);
// Internal string is shown but only in assertion message
auto cmdName = type->GetSymbol().Internal();
wxASSERT_MSG(mCmdMap.find(cmdName) == mCmdMap.end()
wxASSERT_MSG(sCmdMap().find(cmdName) == sCmdMap().end()
, wxT("A command named ") + cmdName
+ wxT(" already exists."));
mCmdMap[cmdName] = std::move(type);
sCmdMap()[cmdName] = std::move(type);
}
CommandDirectory *CommandDirectory::Get()

View File

@ -31,8 +31,17 @@ class CommandDirectory
{
private:
static std::unique_ptr<CommandDirectory> mInstance;
CommandMap mCmdMap;
static CommandMap &sCmdMap();
static void AddCommand(std::unique_ptr<OldStyleCommandType> type);
public:
/// Register a type of command with the directory with a statically
/// constructed instance of this class.
struct RegisterType{
RegisterType( std::unique_ptr<OldStyleCommandType> type )
{ AddCommand( std::move( type ) ); }
};
~CommandDirectory();
/// If a command with the given name has been registered in the directory,
@ -40,9 +49,6 @@ public:
/// Otherwise return NULL.
OldStyleCommandType *LookUp(const wxString &cmdName) const;
/// Register a type of command with the directory.
void AddCommand(std::unique_ptr<OldStyleCommandType> &&type);
/// Get a pointer to the singleton instance
static CommandDirectory *Get();

View File

@ -24,6 +24,7 @@
#include "AppCommandEvent.h"
#include "ScriptCommandRelay.h"
#include "../commands/CommandContext.h"
#include "../commands/Command.h"
CommandHandler::CommandHandler()
: mCurrentContext(std::make_unique<CommandContext>
@ -59,5 +60,5 @@ void CommandHandler::OnReceiveCommand(AppCommandEvent &event)
wxUnusedVar(result);
// Redraw the project
mCurrentContext->GetProject()->RedrawProject();
mCurrentContext->project.RedrawProject();
}

View File

@ -25,7 +25,7 @@ class CommandContext;
class CommandHandler
{
private:
std::unique_ptr<CommandContext> mCurrentContext;
std::unique_ptr<const CommandContext> mCurrentContext;
public:
CommandHandler();

View File

@ -24,9 +24,10 @@ capture the more lengthy output from some commands.
#include "../Audacity.h"
#include "CommandTargets.h"
#include <wx/app.h>
#include <wx/statusbr.h>
#include <wx/string.h>
#include "../ShuttleGui.h"
#include "../Project.h"
#include "../widgets/ErrorDialog.h"
void CommandMessageTarget::StartArray()
@ -375,7 +376,8 @@ void LongMessageDialog::OnCancel(wxCommandEvent & WXUNUSED(evt)){
void LongMessageDialog::AcceptText( const wxString & Text )
{
if( pDlg == NULL ){
pDlg = new LongMessageDialog( GetActiveProject(), _( "Long Message" ) );
pDlg = new LongMessageDialog(
wxTheApp->GetTopWindow(), _( "Long Message" ) );
pDlg->Init();
pDlg->Show();
}

View File

@ -46,10 +46,6 @@ bool CompareAudioCommand::DefineParams( ShuttleParams & S ){
return true;
}
bool CompareAudioCommand::Apply(){
return true;
}
void CompareAudioCommand::PopulateOrExchange(ShuttleGui & S)
{
S.AddSpace(0, 5);
@ -107,7 +103,7 @@ inline int min(int a, int b)
bool CompareAudioCommand::Apply(const CommandContext & context)
{
if (!GetSelection(context, *context.GetProject()))
if (!GetSelection(context, context.project))
{
return false;
}

View File

@ -33,7 +33,6 @@ public:
wxString GetDescription() override {return _("Compares a range on two tracks.");};
bool DefineParams( ShuttleParams & S ) override;
void PopulateOrExchange(ShuttleGui & S) override;
bool Apply() override;
// AudacityCommand overrides
wxString ManualPage() override {return wxT("Extra_Menu:_Scriptables_II#compare_Audio");};

View File

@ -90,7 +90,7 @@ bool DragCommand::Apply(const CommandContext & context)
if( !bHasToY )
mToY = 10;
wxWindow * pWin = context.GetProject();
wxWindow * pWin = &context.project;
wxWindow * pWin1 = nullptr;
wxMouseEvent Evt( wxEVT_MOTION );
Evt.m_x = mFromX;

View File

@ -121,7 +121,7 @@ bool GetInfoCommand::Apply(const CommandContext &context)
if( mFormat == kLisp )
{
CommandContext LispyContext(
*(context.GetProject()),
context.project,
std::make_unique<LispifiedCommandOutputTargets>( *context.pOutput.get() )
);
return ApplyInner( LispyContext );
@ -130,7 +130,7 @@ bool GetInfoCommand::Apply(const CommandContext &context)
if( mFormat == kBrief )
{
CommandContext BriefContext(
*(context.GetProject()),
context.project,
std::make_unique<BriefCommandOutputTargets>( *context.pOutput.get() )
);
return ApplyInner( BriefContext );
@ -159,7 +159,7 @@ bool GetInfoCommand::ApplyInner(const CommandContext &context)
bool GetInfoCommand::SendMenus(const CommandContext &context)
{
wxMenuBar * pBar = context.GetProject()->GetMenuBar();
wxMenuBar * pBar = context.project.GetMenuBar();
if(!pBar ){
wxLogDebug("No menus");
return false;
@ -418,10 +418,10 @@ wxSpinCtrl * ShuttleGuiGetDefinition::TieSpinCtrl(
bool GetInfoCommand::SendPreferences(const CommandContext &context)
{
context.StartArray();
GlobalPrefsDialog dialog( context.GetProject() );
GlobalPrefsDialog dialog( &context.project );
// wxCommandEvent Evt;
//dialog.Show();
wxWindow * pWin = context.GetProject();
wxWindow * pWin = &context.project;
ShuttleGuiGetDefinition S(pWin, *((context.pOutput)->mStatusTarget) );
dialog.ShuttleAll( S );
context.EndArray();
@ -454,7 +454,7 @@ bool GetInfoCommand::SendCommands(const CommandContext &context, int flags )
bool GetInfoCommand::SendBoxes(const CommandContext &context)
{
//context.Status("Boxes");
wxWindow * pWin = context.GetProject();
wxWindow * pWin = &context.project;
context.StartArray();
wxRect R = pWin->GetScreenRect();
@ -483,11 +483,11 @@ bool GetInfoCommand::SendBoxes(const CommandContext &context)
bool GetInfoCommand::SendTracks(const CommandContext & context)
{
TrackList *projTracks = context.GetProject()->GetTracks();
TrackList *projTracks = context.project.GetTracks();
context.StartArray();
for (auto trk : projTracks->Leaders())
{
TrackPanel *panel = context.GetProject()->GetTrackPanel();
TrackPanel *panel = context.project.GetTrackPanel();
Track * fTrack = panel->GetFocusedTrack();
context.StartStruct();
@ -530,7 +530,7 @@ bool GetInfoCommand::SendTracks(const CommandContext & context)
bool GetInfoCommand::SendClips(const CommandContext &context)
{
TrackList *tracks = context.GetProject()->GetTracks();
TrackList *tracks = context.project.GetTracks();
int i=0;
context.StartArray();
for (auto waveTrack : tracks->Leaders<WaveTrack>()) {
@ -552,7 +552,7 @@ bool GetInfoCommand::SendClips(const CommandContext &context)
bool GetInfoCommand::SendEnvelopes(const CommandContext &context)
{
TrackList *tracks = context.GetProject()->GetTracks();
TrackList *tracks = context.project.GetTracks();
int i=0;
int j=0;
context.StartArray();
@ -589,7 +589,7 @@ bool GetInfoCommand::SendEnvelopes(const CommandContext &context)
bool GetInfoCommand::SendLabels(const CommandContext &context)
{
TrackList *tracks = context.GetProject()->GetTracks();
TrackList *tracks = context.project.GetTracks();
int i=0;
context.StartArray();
for (auto t : tracks->Leaders()) {
@ -640,7 +640,7 @@ void GetInfoCommand::ExploreMenu( const CommandContext &context, wxMenu * pMenu,
if( !pMenu )
return;
CommandManager * pMan = context.GetProject()->GetCommandManager();
CommandManager * pMan = context.project.GetCommandManager();
wxMenuItemList list = pMenu->GetMenuItems();
size_t lcnt = list.size();
@ -714,7 +714,7 @@ void GetInfoCommand::ExploreAdornments( const CommandContext &context,
void GetInfoCommand::ExploreTrackPanel( const CommandContext &context,
wxPoint P, wxWindow * pWin, int WXUNUSED(Id), int depth )
{
AudacityProject * pProj = context.GetProject();
AudacityProject * pProj = &context.project;
TrackPanel * pTP = pProj->GetTrackPanel();
wxRect trackRect = pWin->GetRect();

View File

@ -40,7 +40,7 @@ void ImportCommand::PopulateOrExchange(ShuttleGui & S)
}
bool ImportCommand::Apply(const CommandContext & context){
return context.GetProject()->Import(mFileName);
return context.project.Import(mFileName);
}
@ -66,8 +66,8 @@ void ExportCommand::PopulateOrExchange(ShuttleGui & S)
bool ExportCommand::Apply(const CommandContext & context)
{
double t0, t1;
t0 = context.GetProject()->mViewInfo.selectedRegion.t0();
t1 = context.GetProject()->mViewInfo.selectedRegion.t1();
t0 = context.project.mViewInfo.selectedRegion.t0();
t1 = context.project.mViewInfo.selectedRegion.t1();
// Find the extension and check it's valid
int splitAt = mFileName.Find(wxUniChar('.'), true);
@ -80,7 +80,7 @@ bool ExportCommand::Apply(const CommandContext & context)
Exporter exporter;
bool exportSuccess = exporter.Process(context.GetProject(),
bool exportSuccess = exporter.Process(&context.project,
std::max(0, mnChannels),
extension, mFileName,
true, t0, t1);

View File

@ -44,17 +44,17 @@ void OpenProjectCommand::PopulateOrExchange(ShuttleGui & S)
bool OpenProjectCommand::Apply(const CommandContext & context){
auto oldFileName = context.GetProject()->GetFileName();
auto oldFileName = context.project.GetFileName();
if(mFileName.empty())
{
auto project = context.GetProject();
auto project = &context.project;
AudacityProject::OpenFiles(project);
}
else
{
context.GetProject()->OpenFile(mFileName, mbAddToHistory);
context.project.OpenFile(mFileName, mbAddToHistory);
}
const auto &newFileName = context.GetProject()->GetFileName();
const auto &newFileName = context.project.GetFileName();
// Because Open does not return a success or failure, we have to guess
// at this point, based on whether the project file name has
@ -85,7 +85,7 @@ void SaveProjectCommand::PopulateOrExchange(ShuttleGui & S)
bool SaveProjectCommand::Apply(const CommandContext &context)
{
if(mFileName.empty())
return context.GetProject()->SaveAs(mbCompress);
return context.project.SaveAs(mbCompress);
else
return context.GetProject()->SaveAs(mFileName,mbCompress,mbAddToHistory);
return context.project.SaveAs(mFileName,mbCompress,mbAddToHistory);
}

View File

@ -20,6 +20,8 @@ small calculations of rectangles.
#include "../Audacity.h"
#include "ScreenshotCommand.h"
#include <mutex>
#include "../Project.h"
#include <wx/toplevel.h>
#include <wx/dcscreen.h>
@ -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 );
@ -579,7 +594,7 @@ void ScreenshotCommand::CaptureScriptables(
void ScreenshotCommand::CaptureCommands(
const CommandContext & context, const wxArrayStringEx & Commands ){
AudacityProject * pProject = context.GetProject();
AudacityProject * pProject = &context.project;
CommandManager * pMan = pProject->GetCommandManager();
wxString Str;
// Yucky static variables. Is there a better way? The problem is that we need the
@ -792,16 +807,16 @@ bool ScreenshotCommand::Apply(const CommandContext & context)
GetDerivedParams();
//Don't reset the toolbars to a known state.
//We will be capturing variations of them.
//context.GetProject()->GetToolManager()->Reset();
//context.project.GetToolManager()->Reset();
wxTopLevelWindow *w = GetFrontWindow(context.GetProject());
wxTopLevelWindow *w = GetFrontWindow(&context.project);
if (!w)
return false;
TrackPanel *panel = context.GetProject()->GetTrackPanel();
TrackPanel *panel = context.project.GetTrackPanel();
AdornedRulerPanel *ruler = panel->mRuler;
int nTracks = context.GetProject()->GetTracks()->size();
int nTracks = context.project.GetTracks()->size();
int x1,y1,x2,y2;
w->ClientToScreen(&x1, &y1);
@ -811,47 +826,47 @@ bool ScreenshotCommand::Apply(const CommandContext & context)
switch (mCaptureMode) {
case kwindow:
return Capture(context, WindowFileName( context.GetProject(), w ) , w, GetWindowRect(w));
return Capture(context, WindowFileName( &context.project, w ) , w, GetWindowRect(w));
case kfullwindow:
case kwindowplus:
return Capture(context, WindowFileName( context.GetProject(), w ) , w, GetFullWindowRect(w));
return Capture(context, WindowFileName( &context.project, w ) , w, GetFullWindowRect(w));
case kfullscreen:
return Capture(context, mFileName, w,GetScreenRect());
case ktoolbars:
return CaptureDock(context, context.GetProject()->GetToolManager()->GetTopDock(), mFileName);
return CaptureDock(context, context.project.GetToolManager()->GetTopDock(), mFileName);
case kscriptables:
CaptureScriptables(context, context.GetProject(), mFileName);
CaptureScriptables(context, &context.project, mFileName);
break;
case keffects:
CaptureEffects(context, context.GetProject(), mFileName);
CaptureEffects(context, &context.project, mFileName);
break;
case kpreferences:
CapturePreferences(context, context.GetProject(), mFileName);
CapturePreferences(context, &context.project, mFileName);
break;
case kselectionbar:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), SelectionBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), SelectionBarID, mFileName);
case kspectralselection:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), SpectralSelectionBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), SpectralSelectionBarID, mFileName);
case ktools:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), ToolsBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), ToolsBarID, mFileName);
case ktransport:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), TransportBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), TransportBarID, mFileName);
case kmixer:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), MixerBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), MixerBarID, mFileName);
case kmeter:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), MeterBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), MeterBarID, mFileName);
case krecordmeter:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), RecordMeterBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), RecordMeterBarID, mFileName);
case kplaymeter:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), PlayMeterBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), PlayMeterBarID, mFileName);
case kedit:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), EditBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), EditBarID, mFileName);
case kdevice:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), DeviceBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), DeviceBarID, mFileName);
case ktranscription:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), TranscriptionBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), TranscriptionBarID, mFileName);
case kscrub:
return CaptureToolbar(context, context.GetProject()->GetToolManager(), ScrubbingBarID, mFileName);
return CaptureToolbar(context, context.project.GetToolManager(), ScrubbingBarID, mFileName);
case ktrackpanel:
return Capture(context, mFileName, panel, GetPanelRect(panel));
case kruler:
@ -859,9 +874,9 @@ bool ScreenshotCommand::Apply(const CommandContext & context)
case ktracks:
return Capture(context, mFileName, panel, GetTracksRect(panel));
case kfirsttrack:
return Capture(context, mFileName, panel, GetTrackRect( context.GetProject(), panel, 0 ) );
return Capture(context, mFileName, panel, GetTrackRect( &context.project, panel, 0 ) );
case ksecondtrack:
return Capture(context, mFileName, panel, GetTrackRect( context.GetProject(), panel, 1 ) );
return Capture(context, mFileName, panel, GetTrackRect( &context.project, panel, 1 ) );
case ktracksplus:
{ wxRect r = GetTracksRect(panel);
r.SetTop( r.GetTop() - ruler->GetRulerHeight() );
@ -869,36 +884,36 @@ bool ScreenshotCommand::Apply(const CommandContext & context)
return Capture(context, mFileName, panel, r);
}
case kfirsttrackplus:
{ wxRect r = GetTrackRect(context.GetProject(), panel, 0 );
{ wxRect r = GetTrackRect(&context.project, panel, 0 );
r.SetTop( r.GetTop() - ruler->GetRulerHeight() );
r.SetHeight( r.GetHeight() + ruler->GetRulerHeight() );
return Capture(context, mFileName, panel, r );
}
case kfirsttwotracks:
{ wxRect r = GetTrackRect( context.GetProject(), panel, 0 );
r = r.Union( GetTrackRect( context.GetProject(), panel, 1 ));
{ wxRect r = GetTrackRect( &context.project, panel, 0 );
r = r.Union( GetTrackRect( &context.project, panel, 1 ));
return Capture(context, mFileName, panel, r );
}
case kfirstthreetracks:
{ wxRect r = GetTrackRect( context.GetProject(), panel, 0 );
r = r.Union( GetTrackRect( context.GetProject(), panel, 2 ));
{ wxRect r = GetTrackRect( &context.project, panel, 0 );
r = r.Union( GetTrackRect( &context.project, panel, 2 ));
return Capture(context, mFileName, panel, r );
}
case kfirstfourtracks:
{ wxRect r = GetTrackRect( context.GetProject(), panel, 0 );
r = r.Union( GetTrackRect( context.GetProject(), panel, 3 ));
{ wxRect r = GetTrackRect( &context.project, panel, 0 );
r = r.Union( GetTrackRect( &context.project, panel, 3 ));
return Capture(context, mFileName, panel, r );
}
case kalltracks:
{ wxRect r = GetTrackRect( context.GetProject(), panel, 0 );
r = r.Union( GetTrackRect( context.GetProject(), panel, nTracks-1 ));
{ wxRect r = GetTrackRect( &context.project, panel, 0 );
r = r.Union( GetTrackRect( &context.project, panel, nTracks-1 ));
return Capture(context, mFileName, panel, r );
}
case kalltracksplus:
{ wxRect r = GetTrackRect( context.GetProject(), panel, 0 );
{ wxRect r = GetTrackRect( &context.project, panel, 0 );
r.SetTop( r.GetTop() - ruler->GetRulerHeight() );
r.SetHeight( r.GetHeight() + ruler->GetRulerHeight() );
r = r.Union( GetTrackRect( context.GetProject(), panel, nTracks-1 ));
r = r.Union( GetTrackRect( &context.project, panel, nTracks-1 ));
return Capture(context, mFileName, panel, r );
}
default:

View File

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

View File

@ -24,8 +24,8 @@ code out of ModuleManager.
#include "CommandTargets.h"
#include "CommandBuilder.h"
#include "AppCommandEvent.h"
#include "../Project.h"
#include <wx/app.h>
#include <wx/window.h>
#include <wx/string.h>
// Declare static class members
@ -52,13 +52,16 @@ void ScriptCommandRelay::Run()
}
/// Send a command to a project, to be applied in that context.
void ScriptCommandRelay::PostCommand(AudacityProject *project, const OldStyleCommandPointer &cmd)
void ScriptCommandRelay::PostCommand(
wxWindow *pWindow, const OldStyleCommandPointer &cmd)
{
wxASSERT(project != NULL);
wxASSERT( pWindow );
wxASSERT(cmd != NULL);
AppCommandEvent ev;
ev.SetCommand(cmd);
project->GetEventHandler()->AddPendingEvent(ev);
if ( pWindow ) {
AppCommandEvent ev;
ev.SetCommand(cmd);
pWindow->GetEventHandler()->AddPendingEvent(ev);
}
}
/// This is the function which actually obeys one command. Rather than applying
@ -71,9 +74,8 @@ int ExecCommand(wxString *pIn, wxString *pOut)
CommandBuilder builder(*pIn);
if (builder.WasValid())
{
AudacityProject *project = GetActiveProject();
OldStyleCommandPointer cmd = builder.GetCommand();
ScriptCommandRelay::PostCommand(project, cmd);
ScriptCommandRelay::PostCommand(wxTheApp->GetTopWindow(), cmd);
*pOut = wxEmptyString;
}

View File

@ -20,11 +20,11 @@
#include "../MemoryX.h"
class wxWindow;
class CommandHandler;
class ResponseQueue;
class Response;
class ResponseQueueTarget;
class AudacityProject;
class OldStyleCommand;
using OldStyleCommandPointer = std::shared_ptr<OldStyleCommand>;
class wxString;
@ -50,7 +50,8 @@ class ScriptCommandRelay
static void SetCommandHandler(CommandHandler &ch);
static void Run();
static void PostCommand(AudacityProject *project, const OldStyleCommandPointer &cmd);
static void PostCommand(
wxWindow *pWindow, const OldStyleCommandPointer &cmd);
static void SendResponse(const wxString &response);
static Response ReceiveResponse();
static std::shared_ptr<ResponseQueueTarget> GetResponseTarget();

View File

@ -85,7 +85,7 @@ void SelectTimeCommand::PopulateOrExchange(ShuttleGui & S)
bool SelectTimeCommand::Apply(const CommandContext & context){
// Many commands need focus on track panel.
// No harm in setting it with a scripted select.
context.GetProject()->GetTrackPanel()->SetFocus();
context.project.GetTrackPanel()->SetFocus();
if( !bHasT0 && !bHasT1 )
return true;
@ -97,7 +97,7 @@ bool SelectTimeCommand::Apply(const CommandContext & context){
if( !bHasRelativeSpec )
mRelativeTo = 0;
AudacityProject * p = context.GetProject();
AudacityProject * p = &context.project;
double end = p->GetTracks()->GetEndTime();
double t0;
double t1;
@ -164,7 +164,7 @@ bool SelectFrequenciesCommand::Apply(const CommandContext & context){
if( !bHasBottom )
mBottom = 0.0;
context.GetProject()->SSBL_ModifySpectralSelection(
context.project.SSBL_ModifySpectralSelection(
mBottom, mTop, false);// false for not done.
return true;
}
@ -214,7 +214,7 @@ bool SelectTracksCommand::Apply(const CommandContext &context)
// Used to invalidate cached selection and tracks.
Effect::IncEffectCounter();
int index = 0;
TrackList *tracks = context.GetProject()->GetTracks();
TrackList *tracks = context.project.GetTracks();
// Defaults if no value...
if( !bHasNumTracks )

View File

@ -66,8 +66,8 @@ bool SetLabelCommand::Apply(const CommandContext & context)
// this code could be put in subroutines/reduced.
//wxString mode = GetString(wxT("Type"));
AudacityProject * p = context.GetProject();
TrackList *tracks = context.GetProject()->GetTracks();
AudacityProject * p = &context.project;
TrackList *tracks = context.project.GetTracks();
LabelStruct * pLabel = NULL;
int i=0;
int nn=0;

View File

@ -66,7 +66,7 @@ void SetProjectCommand::PopulateOrExchange(ShuttleGui & S)
bool SetProjectCommand::Apply(const CommandContext & context)
{
AudacityProject * pProj = context.GetProject();
AudacityProject * pProj = &context.project;
if( bHasName )
pProj->SetLabel(mName);

View File

@ -94,7 +94,7 @@ bool SetTrackBase::Apply(const CommandContext & context )
{
long i = 0;// track counter
long j = 0;// channel counter
auto tracks = context.GetProject()->GetTracks();
auto tracks = context.project.GetTracks();
for ( auto t : tracks->Leaders() )
{
auto channels = TrackList::Channels(t);
@ -163,7 +163,7 @@ bool SetTrackStatusCommand::ApplyInner(const CommandContext & context, Track * t
if( !bIsSecondChannel ){
if( bHasFocused )
{
TrackPanel *panel = context.GetProject()->GetTrackPanel();
TrackPanel *panel = context.project.GetTrackPanel();
if( bFocused)
panel->SetFocusedTrack( t );
else if( t== panel->GetFocusedTrack() )

View File

@ -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 <Cocoa/Cocoa.h>
#endif
#include "../commands/ScreenshotCommand.h"
#include <unordered_map>
// Effect application counter
@ -109,6 +108,25 @@ const wxString Effect::kFactoryDefaultsIdent = wxT("<Factory Defaults>");
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 )
@ -3303,7 +3322,9 @@ void EffectUIHost::OnApply(wxCommandEvent & evt)
if( mEffect )
mEffect->Apply();
if( mCommand )
mCommand->Apply();
// PRL: I don't like the global and would rather pass *mProject!
// But I am preserving old behavior
mCommand->Apply( CommandContext{ *GetActiveProject() } );
}
void EffectUIHost::DoCancel()

View File

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

View File

@ -35,6 +35,7 @@ effects.
#include "../ShuttleGetDefinition.h"
#include "../commands/CommandContext.h"
#include "../commands/Command.h"
#include "../PluginManager.h"