Audacity 3.2.0
EffectAndCommandPluginManager.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 EffectAndCommandManager.cpp
6
7 Split from EffectManager.cpp
8
9**********************************************************************/
11#include "BasicUI.h"
12#include "CommandContext.h"
13#include "Effect.h"
14#include "EffectManager.h"
15#include "PluginManager.h"
17#include "Track.h"
19
21{
23 return ecm;
24}
25
27 const PluginID& ID, const CommandContext& context,
28 bool shouldPrompt /* = true */)
29
30{
33
34 if (!command)
35 {
36 return false;
37 }
38
39 bool res = command->DoAudacityCommand(context, shouldPrompt);
40
41 return res;
42}
43
46{
47 // Must have a "valid" ID
48 if (ID.empty())
49 {
50 return NULL;
51 }
52
53 if (mCommands.find(ID) == mCommands.end())
54 {
55 // This will instantiate the command if it hasn't already been done
56 auto command =
57 dynamic_cast<AudacityCommand*>(PluginManager::Get().Load(ID));
58 if (command)
59 {
60 command->Init();
61 mCommands[ID] = command;
62 return command;
63 }
64
66 XO("Attempting to initialize the following command failed:\n\n%s\n\nMore information may be available in 'Help > Diagnostics > Show Log'")
67 .Format(PluginManager::Get().GetName(ID)),
69 XO("Command failed to initialize")));
70
71 return NULL;
72 }
73
74 return mCommands[ID];
75}
76
78{
79 if (auto pEff = EffectManager::Get().GetEffect(ID))
80 return pEff->GetDefinition().ManualPage();
82 if (pCom)
83 return pCom->ManualPage();
84
85 return wxEmptyString;
86}
87
90{
91 if (auto pEff = EffectManager::Get().GetEffect(ID))
92 return pEff->GetDefinition().GetDescription();
94 if (pCom)
95 return pCom->GetDescription();
96
97 return {};
98}
99
101 const PluginID& ID, const CommandContext& context, int flags)
102{
103 const EffectSettingsManager* effect = nullptr;
105 AudacityCommand* command = nullptr;
106
107 if (auto [edi, pSettings] =
108 EffectManager::Get().GetEffectAndDefaultSettings(ID);
109 edi)
110 {
111 effect = &edi->GetDefinition();
112 assert(pSettings); // postcondition
113 settings = pSettings;
114 }
115 else
116 command = GetAudacityCommand(ID);
117 if (!effect && !command)
118 return;
119
120 ConstSettingsVisitor NullShuttle;
121
122 // Test if it defines any parameters at all.
123 bool bHasParams = command ? command->VisitSettings(NullShuttle) :
124 effect->VisitSettings(NullShuttle, *settings);
125 if ((flags == 0) && !bHasParams)
126 return;
127
128 // This is capturing the output context into the shuttle.
129 ShuttleGetDefinition S(*context.pOutput.get()->mStatusTarget.get());
130 S.StartStruct();
131 // using GET to expose a CommandID to the user!
132 // Macro command details are one place that we do expose Identifier
133 // to (more sophisticated) users
134 const auto& pm = PluginManager::Get();
135 S.AddItem(pm.GetCommandIdentifier(ID).GET(), "id");
136 S.AddItem(pm.GetName(ID).Translation(), "name");
137 if (bHasParams)
138 {
139 S.StartField("params");
140 S.StartArray();
141 command ? command->VisitSettings(S) : effect->VisitSettings(S, *settings);
142 S.EndArray();
143 S.EndField();
144 }
145 // use GET() to expose some details to macro programming users
146 S.AddItem(GetCommandUrl(ID).GET(), "url");
147 // The tip is a translated string!
148 S.AddItem(GetCommandTip(ID).Translation(), "tip");
149 S.EndStruct();
150}
151
153{
154 if (auto effect = EffectManager::Get().GetEffect(ID))
155 effect->SetBatchProcessing();
156 else if (auto command = GetAudacityCommand(ID))
157 command->SetBatchProcessing(true);
158}
159
161{
162 if (auto effect = EffectManager::Get().GetEffect(ID))
163 effect->UnsetBatchProcessing();
164 else if (auto command = GetAudacityCommand(ID))
165 command->SetBatchProcessing(false);
166}
167
168// This function is used only in the macro programming user interface
170{
172 if (auto effect = pair.first)
173 {
174 assert(pair.second); // postcondition
175 wxString parms;
176
177 effect->SaveSettingsAsString(*pair.second, parms);
178
179 // Some effects don't have automatable parameters and will not return
180 // anything, so try to get the active preset (current or factory).
181 if (parms.empty())
182 {
184 }
185
186 return parms;
187 }
188
189 AudacityCommand* command = GetAudacityCommand(ID);
190
191 if (command)
192 {
193 wxString parms;
194
195 command->SaveSettingsAsString(parms);
196
197 // Some effects don't have automatable parameters and will not return
198 // anything, so try to get the active preset (current or factory).
199 if (parms.empty())
200 {
202 }
203
204 return parms;
205 }
206 return wxEmptyString;
207}
208
209// This function is used only in the macro programming user interface
211 const PluginID& ID, const wxString& params)
212{
214 if (auto effect = pair.first)
215 {
216 assert(pair.second); // postcondition
217 auto& settings = *pair.second;
219
220 // Check first for what GetDefaultPreset() might have written
221 if (eap.HasEntry(wxT("Use Preset")))
222 {
223 return effect
224 ->LoadSettingsFromString(eap.Read(wxT("Use Preset")), settings)
225 .has_value();
226 }
227
228 return effect->LoadSettingsFromString(params, settings).has_value();
229 }
230 AudacityCommand* command = GetAudacityCommand(ID);
231
232 if (command)
233 {
234 // Set defaults (if not initialised) before setting values.
235 command->Init();
237
238 // Check first for what GetDefaultPreset() might have written
239 if (eap.HasEntry(wxT("Use Preset")))
240 {
241 return command->LoadSettingsFromString(eap.Read(wxT("Use Preset")));
242 }
243
244 return command->LoadSettingsFromString(params);
245 }
246 return false;
247}
248
250
254 const PluginID& ID, AudacityProject& project, DialogInvoker dialogInvoker)
255{
256 bool result = false;
257 if (auto effect = dynamic_cast<Effect*>(EffectManager::Get().GetEffect(ID)))
258 {
259 auto empty = TrackList::Create(nullptr);
260 auto pEffectBase = dynamic_cast<EffectBase*>(effect);
261 if (pEffectBase)
262 // This allows effects to call Init() safely
263 pEffectBase->SetTracks(empty.get());
264 Finally Do([&] {
265 // reverse the side-effect
266 if (pEffectBase)
267 pEffectBase->SetTracks(nullptr);
268 });
269
270 std::shared_ptr<EffectInstance> pInstance;
273 if (const auto pSettings = EffectManager::Get().GetDefaultSettings(ID))
274 result = dialogInvoker(*effect, *pSettings, pInstance);
275 return result;
276 }
277
278 AudacityCommand* command = GetAudacityCommand(ID);
279
280 if (command)
281 {
282 result = command->PromptUser(project);
283 return result;
284 }
285
286 return result;
287}
wxT("CloseDown"))
Toolkit-neutral facade for basic user interface services.
wxString PluginID
EffectDistortionSettings params
XO("Cut/Copy/Paste")
const auto project
#define S(N)
Definition: ToChars.cpp:64
declares abstract base class Track, TrackList, and iterators over TrackList
static Settings & settings()
Definition: TrackInfo.cpp:51
Base class for command in Audacity.
virtual bool Init()
bool LoadSettingsFromString(const wxString &parms)
bool SaveSettingsAsString(wxString &parms)
virtual bool VisitSettings(SettingsVisitor &)
bool DoAudacityCommand(const CommandContext &context, bool shouldPrompt=true)
virtual ManualPageID ManualPage()
virtual bool PromptUser(AudacityProject &)
virtual TranslatableString GetDescription() const override
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
std::unique_ptr< CommandOutputTargets > pOutput
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
virtual bool HasEntry(const wxString &strName) const override
bool PromptUser(const PluginID &ID, AudacityProject &project, DialogInvoker dialogInvoker)
Shows an effect or command dialog so the user can specify settings for later.
std::function< bool(Effect &, EffectSettings &, std::shared_ptr< EffectInstance > &)> DialogInvoker
wxString GetEffectParameters(const PluginID &ID)
void GetCommandDefinition(const PluginID &ID, const CommandContext &context, int flags)
static EffectAndCommandPluginManager & Get()
bool SetEffectParameters(const PluginID &ID, const wxString &params)
bool DoAudacityCommand(const PluginID &ID, const CommandContext &, bool shouldPrompt=true)
AudacityCommand * GetAudacityCommand(const PluginID &ID)
ManualPageID GetCommandUrl(const PluginID &ID)
TranslatableString GetCommandTip(const PluginID &ID)
Base class for many of the effects in Audacity.
Definition: EffectBase.h:33
void SetTracks(TrackList *pTracks)
Definition: EffectBase.cpp:43
Base class for many of the effects in Audacity.
Definition: Effect.h:26
void SetSkipStateFlag(bool flag)
std::pair< EffectPlugin *, EffectSettings * > GetEffectAndDefaultSettings(const PluginID &ID)
static EffectManager & Get()
wxString GetDefaultPreset(const PluginID &ID)
EffectSettingsManager is an EffectDefinitionInterface that adds a factory function for EffectSettings...
virtual bool VisitSettings(SettingsVisitor &visitor, EffectSettings &settings)
Abstract base class used in importing a file.
ComponentInterface * Load(const PluginID &ID)
static PluginManager & Get()
Visitor of effect or command parameters. This is a base class with lots of virtual functions that do ...
SettingsVisitor that retrieves a JSON format definition of a command's parameters.
static TrackListHolder Create(AudacityProject *pOwner)
Definition: Track.cpp:330
Holds a msgid for the translation catalog; may also bind format arguments.
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:287
MessageBoxOptions && Caption(TranslatableString caption_) &&
Definition: BasicUI.h:101
Externalized state of a plug-in.
"finally" as in The C++ Programming Language, 4th ed., p. 358 Useful for defining ad-hoc RAII actions...
Definition: MemoryX.h:175