audacia/src/commands/CommandBuilder.cpp
James Crook b1b1a362ed Doxygen, Clips and Labels
- Classes renamed and better doxygenated
- GetInfo: Type=Clips added
- GetInfo: Type=Labels added.
2018-02-24 14:20:24 -05:00

210 lines
5.7 KiB
C++

/**********************************************************************
Audacity - A Digital Audio Editor
Copyright 1999-2009 Audacity Team
File License: wxWidgets
Dan Horgan
******************************************************************//**
\file CommandBuilder.cpp
\brief Contains definitions for CommandBuilder class.
\class CommandBuilder
\brief A type of factory for Commands of various sorts.
CommandBuilder has the task of deciding what command is meant by a given
command string, and producing a suitable command object. For now, it doesn't
actually do any processing - it just passes everything on to the BatchCommand
system by constructing BatchCommandEval objects.
*//*******************************************************************/
#include "../Audacity.h"
#include "CommandBuilder.h"
#include "CommandDirectory.h"
#include "../Shuttle.h"
#include "BatchEvalCommand.h"
#include "Command.h"
#include "CommandTargets.h"
#include "ScriptCommandRelay.h"
#include "CommandContext.h"
CommandBuilder::CommandBuilder(const wxString &cmdString)
: mValid(false)
{
BuildCommand(cmdString);
}
CommandBuilder::CommandBuilder(const wxString &cmdName, const wxString &params)
: mValid(false)
{
BuildCommand(cmdName, params);
}
CommandBuilder::~CommandBuilder()
{
}
bool CommandBuilder::WasValid()
{
return mValid;
}
const wxString &CommandBuilder::GetErrorMessage()
{
return mError;
}
OldStyleCommandPointer CommandBuilder::GetCommand()
{
wxASSERT(mValid);
wxASSERT(mCommand);
auto result = mCommand;
mCommand.reset();
return result;
}
void CommandBuilder::Failure(const wxString &msg)
{
mError = msg;
mValid = false;
}
void CommandBuilder::Success(const OldStyleCommandPointer &cmd)
{
mCommand = cmd;
mValid = true;
}
void CommandBuilder::BuildCommand(const wxString &cmdName,
const wxString &cmdParamsArg)
{
// Stage 1: create a Command object of the right type
auto scriptOutput = ScriptCommandRelay::GetResponseTarget();
auto output
= std::make_unique<CommandOutputTargets>(std::make_unique<NullProgressTarget>(),
scriptOutput,
scriptOutput);
#ifdef OLD_BATCH_SYSTEM
OldStyleCommandType *factory = CommandDirectory::Get()->LookUp(cmdName);
if (factory == NULL)
{
// Fall back to hoping the Batch Command system can handle it
#endif
OldStyleCommandType *type = CommandDirectory::Get()->LookUp(wxT("BatchCommand"));
wxASSERT(type != NULL);
mCommand = type->Create(nullptr);
mCommand->SetParameter(wxT("CommandName"), cmdName);
mCommand->SetParameter(wxT("ParamString"), cmdParamsArg);
auto aCommand = std::make_shared<ApplyAndSendResponse>(mCommand, output);
Success(aCommand);
return;
#ifdef OLD_BATCH_SYSTEM
}
CommandSignature &signature = factory->GetSignature();
mCommand = factory->Create(nullptr);
//mCommand->SetOutput( std::move(output) );
// Stage 2: set the parameters
ShuttleCli shuttle;
shuttle.mParams = cmdParamsArg;
shuttle.mbStoreInClient = true;
ParamValueMap::const_iterator iter;
ParamValueMap params = signature.GetDefaults();
// Iterate through the parameters defined by the command
for (iter = params.begin(); iter != params.end(); ++iter)
{
wxString paramString;
// IF there is a match in the args actually used
if (shuttle.TransferString(iter->first, paramString, wxT("")))
{
// Then set that parameter.
if (!mCommand->SetParameter(iter->first, paramString))
{
Failure();
return;
}
}
}
// Check for unrecognised parameters
wxString cmdParams(cmdParamsArg);
while (cmdParams != wxEmptyString)
{
cmdParams.Trim(true);
cmdParams.Trim(false);
int splitAt = cmdParams.Find(wxT('='));
if (splitAt < 0 && cmdParams != wxEmptyString)
{
Failure(wxT("Parameter string is missing '='"));
return;
}
wxString paramName = cmdParams.Left(splitAt);
if (params.find(paramName) == params.end())
{
Failure(wxT("Unrecognized parameter: '") + paramName + wxT("'"));
return;
}
// Handling of quoted strings is quite limitted.
// You start and end with a " or a '.
// There is no escaping in the string.
cmdParams = cmdParams.Mid(splitAt+1);
if( cmdParams.IsEmpty() )
splitAt =-1;
else if( cmdParams[0] == '\"' ){
cmdParams = cmdParams.Mid(1);
splitAt = cmdParams.Find(wxT('\"'))+1;
}
else if( cmdParams[0] == '\'' ){
cmdParams = cmdParams.Mid(1);
splitAt = cmdParams.Find(wxT('\''))+1;
}
else
splitAt = cmdParams.Find(wxT(' '))+1;
if (splitAt < 1)
{
splitAt = cmdParams.Len();
}
cmdParams = cmdParams.Mid(splitAt);
}
auto aCommand = std::make_shared<ApplyAndSendResponse>(mCommand, output);
Success(aCommand);
#endif
}
void CommandBuilder::BuildCommand(const wxString &cmdStringArg)
{
wxString cmdString(cmdStringArg);
// Find the command name terminator... If there is more than one word and
// no terminator, the command is badly formed
cmdString.Trim(true); cmdString.Trim(false);
int splitAt = cmdString.Find(wxT(':'));
if (splitAt < 0 && cmdString.Find(wxT(' ')) >= 0) {
mError = wxT("Command is missing ':'");
ScriptCommandRelay::SendResponse(wxT("\n"));
mValid = false;
return;
}
wxString cmdName = cmdString.Left(splitAt);
wxString cmdParams = cmdString.Mid(splitAt+1);
if( splitAt < 0 )
cmdParams = "";
cmdName.Trim(true);
cmdParams.Trim(false);
BuildCommand(cmdName, cmdParams);
}