Audacity 3.2.0
CommandBuilder.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity - A Digital Audio Editor
4 Copyright 1999-2009 Audacity Team
5 File License: wxWidgets
6
7 Dan Horgan
8
9******************************************************************//*******************************************************************/
23
24
25#include "CommandBuilder.h"
26
27#include "CommandDirectory.h"
28#include "Command.h"
29#include "CommandContext.h"
30#include "CommandTargets.h"
31#include "SettingsVisitor.h"
32
34 AudacityProject &project, const wxString &cmdString)
35 : mValid(false)
36{
37 BuildCommand(project, cmdString);
38}
39
41 const wxString &cmdName, const wxString &params)
42 : mValid(false)
43{
44 BuildCommand(project, cmdName, params);
45}
46
48{
49}
50
52{
53 return mValid;
54}
55
57{
58 wxASSERT(mValid);
59 wxASSERT(mCommand);
60 auto result = mCommand;
61 mCommand.reset();
62 return result;
63}
64
66{
67 if (!mValid && !mError.empty()) {
68 return mError + wxT("\n");
69 }
70 return mResponse->GetResponse() + wxT("\n");
71}
72
73void CommandBuilder::Failure(const wxString &msg)
74{
75 mError = msg;
76 mValid = false;
77}
78
80{
81 mCommand = cmd;
82 mValid = true;
83}
84
85namespace {
86// This class was formerly in Shuttle.cpp and inherited Shuttle but the
87// polymorphism wasn't really needed in the sole use of the class in this file
88struct ShuttleCli final // : public Shuttle
89{
90 wxString mValueString;
91 bool TransferString(const wxString & Name, wxString & strValue);
92 wxString mParams;
93
94// virtual ~ShuttleCli() {}
95
96 bool ExchangeWithMaster(const wxString & Name);
97};
98
99// uses values of the form
100// param1=value1 param2=value2
101bool ShuttleCli::ExchangeWithMaster(const wxString & Name)
102{
103 int i;
104 mParams = L" " + mParams;
105 i = mParams.Find( L" " + Name + L"=" );
106 if( i >= 0 ){
107 int j = i + 2 + Name.Length();
108 wxString terminator = L' ';
109 if (mParams.GetChar(j) == L'"') //Strings are surrounded by quotes
110 {
111 terminator = L'"';
112 j++;
113 }
114 else if(mParams.GetChar(j) == L'\'') // or by single quotes.
115 {
116 terminator = L'\'';
117 j++;
118 }
119 i = j;
120 while( j<(int)mParams.Length() && mParams.GetChar(j) != terminator )
121 j++;
122 mValueString = mParams.Mid(i, j - i);
123 return true;
124 }
125 return false;
126}
127
128bool ShuttleCli::TransferString(const wxString & Name, wxString & strValue)
129{
130 if( ExchangeWithMaster(Name)) {
131 strValue = mValueString;
132 return true;
133 }
134 else
135 return false;
136}
137}
138
140 const wxString &cmdName,
141 const wxString &cmdParamsArg)
142{
143 // Stage 1: create a Command object of the right type
144
145 mResponse = std::make_shared< ResponseTarget >();
146 auto output
147 = std::make_unique<CommandOutputTargets>(std::make_unique<NullProgressTarget>(),
148 mResponse,
149 mResponse);
150
151#ifdef OLD_BATCH_SYSTEM
153
154 if (factory == NULL)
155 {
156 // Fall back to hoping the Batch Command system can handle it
157#endif
158 OldStyleCommandType *type = CommandDirectory::Get()->LookUp(wxT("BatchCommand"));
159 wxASSERT(type != NULL);
160 mCommand = type->Create(project, nullptr);
161 mCommand->SetParameter(wxT("CommandName"), cmdName);
162 mCommand->SetParameter(wxT("ParamString"), cmdParamsArg);
163 auto aCommand = std::make_shared<ApplyAndSendResponse>(mCommand, output);
164 Success(aCommand);
165 return;
166#ifdef OLD_BATCH_SYSTEM
167 }
168
169 CommandSignature &signature = factory->GetSignature();
170 mCommand = factory->Create(nullptr);
171 //mCommand->SetOutput( std::move(output) );
172 // Stage 2: set the parameters
173
174 ShuttleCli shuttle;
175 shuttle.mParams = cmdParamsArg;
176
177 ParamValueMap::const_iterator iter;
178 ParamValueMap params = signature.GetDefaults();
179
180 // Iterate through the parameters defined by the command
181 for (iter = params.begin(); iter != params.end(); ++iter)
182 {
183 wxString paramString;
184 // IF there is a match in the args actually used
185 if (shuttle.TransferString(iter->first, paramString, wxT("")))
186 {
187 // Then set that parameter.
188 if (!mCommand->SetParameter(iter->first, paramString))
189 {
190 Failure();
191 return;
192 }
193 }
194 }
195
196 // Check for unrecognised parameters
197
198 wxString cmdParams(cmdParamsArg);
199
200 while (!cmdParams.empty())
201 {
202 cmdParams.Trim(true);
203 cmdParams.Trim(false);
204 int splitAt = cmdParams.Find(wxT('='));
205 if (splitAt < 0 && !cmdParams.empty())
206 {
207 Failure(wxT("Parameter string is missing '='"));
208 return;
209 }
210 wxString paramName = cmdParams.Left(splitAt);
211 if (params.find(paramName) == params.end())
212 {
213 Failure(wxT("Unrecognized parameter: '") + paramName + wxT("'"));
214 return;
215 }
216 // Handling of quoted strings is quite limited.
217 // You start and end with a " or a '.
218 // There is no escaping in the string.
219 cmdParams = cmdParams.Mid(splitAt+1);
220 if( cmdParams.empty() )
221 splitAt =-1;
222 else if( cmdParams[0] == '\"' ){
223 cmdParams = cmdParams.Mid(1);
224 splitAt = cmdParams.Find(wxT('\"'))+1;
225 }
226 else if( cmdParams[0] == '\'' ){
227 cmdParams = cmdParams.Mid(1);
228 splitAt = cmdParams.Find(wxT('\''))+1;
229 }
230 else
231 splitAt = cmdParams.Find(wxT(' '))+1;
232 if (splitAt < 1)
233 {
234 splitAt = cmdParams.length();
235 }
236 cmdParams = cmdParams.Mid(splitAt);
237 }
238 auto aCommand = std::make_shared<ApplyAndSendResponse>(mCommand, output);
239 Success(aCommand);
240#endif
241}
242
244 AudacityProject &project, const wxString &cmdStringArg)
245{
246 wxString cmdString(cmdStringArg);
247
248 // Find the command name terminator... If there is more than one word and
249 // no terminator, the command is badly formed
250 cmdString.Trim(true); cmdString.Trim(false);
251 int splitAt = cmdString.Find(wxT(':'));
252 if (splitAt < 0 && cmdString.Find(wxT(' ')) >= 0) {
253 Failure(wxT("Syntax error!\nCommand is missing ':'"));
254 return;
255 }
256
257 wxString cmdName = cmdString.Left(splitAt);
258 wxString cmdParams = cmdString.Mid(splitAt+1);
259 if( splitAt < 0 )
260 cmdParams = "";
261
262 cmdName.Trim(true);
263 cmdParams.Trim(false);
264
265 BuildCommand(project, cmdName, cmdParams);
266}
wxT("CloseDown"))
static RegisteredToolbarFactory factory
Contains declaration of Command base class.
Contains declaration of CommandBuilder class.
Contains declarations for CommandDirectory class.
std::map< wxString, wxVariant > ParamValueMap
Definition: CommandMisc.h:23
EffectDistortionSettings params
const auto project
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
void Failure(const wxString &msg={})
void Success(const OldStyleCommandPointer &cmd)
wxString GetResponse()
void BuildCommand(AudacityProject &project, const wxString &cmdName, const wxString &cmdParams)
ResponseTargetPointer mResponse
OldStyleCommandPointer GetCommand()
CommandBuilder(AudacityProject &project, const wxString &cmdString)
OldStyleCommandPointer mCommand
OldStyleCommandType * LookUp(const wxString &cmdName) const
static CommandDirectory * Get()
Get a pointer to the singleton instance.
Class that maps parameter names to default values and validators.
ParamValueMap GetDefaults() const
OldStyleCommandPointer is a unique_ptr to an OldStyleCommand.
Base class for containing data common to all commands of a given type. Also acts as a factory.
Definition: CommandType.h:45
virtual OldStyleCommandPointer Create(AudacityProject &project, std::unique_ptr< CommandOutputTargets > &&target)=0