Audacity 3.2.0
AudacityCommand.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 AudacityCommand.cpp
6
7 James Crook
8
9*******************************************************************//****************************************************************//*******************************************************************/
21
22
23#include "AudacityCommand.h"
24#include "MemoryX.h"
25
26#include "CommandContext.h"
27
28#include <algorithm>
29
30#include <wx/defs.h>
31#include <wx/stockitem.h>
32#include <wx/tglbtn.h>
33#include <wx/log.h>
34
35#include "ConfigInterface.h"
36
37#include "../ShuttleAutomation.h"
38#include "../ShuttleGui.h"
39#include "../widgets/ProgressDialog.h"
40#include "../widgets/HelpSystem.h"
41#include "../widgets/AudacityMessageBox.h"
42#include "../widgets/VetoDialogHook.h"
43
44#include <unordered_map>
45
47{
48 mProgress = NULL;
49 mUIParent = NULL;
50 mUIDialog = NULL;
51 mIsBatch = false;
52 mNeedsInit = true;
53}
54
56{
57 if (mUIDialog)
58 mUIDialog->Close();
59}
60
61
63VendorSymbol AudacityCommand::GetVendor() const { return XO("Audacity");}
64wxString AudacityCommand::GetVersion() const { return AUDACITY_VERSION_STRING;}
65
66
68 if( !mNeedsInit )
69 return true;
70 mNeedsInit = false;
71 ShuttleDefaults DefaultSettingShuttle;
72 return VisitSettings( DefaultSettingShuttle );
73}
74
75bool AudacityCommand::ShowInterface(wxWindow *parent, bool WXUNUSED(forceModal))
76{
77 if (mUIDialog)
78 {
79 if ( mUIDialog->Close(true) )
80 mUIDialog = nullptr;
81 return false;
82 }
83
84 // mUIDialog is null
85 auto cleanup = valueRestorer( mUIDialog );
86
87 mUIDialog = CreateUI(parent, this);
88 if (!mUIDialog)
89 return false;
90
91 mUIDialog->Layout();
92 mUIDialog->Fit();
93 mUIDialog->SetMinSize(mUIDialog->GetSize());
94
95 // The Screenshot command might be popping this dialog up, just to capture it.
97 return false;
98
99 bool res = mUIDialog->ShowModal() != 0;
100 return res;
101}
102
103wxDialog *AudacityCommand::CreateUI(wxWindow *parent, AudacityCommand * WXUNUSED(client))
104{
106 parent, GetName(), this}};
107
108 if (dlg->Init())
109 {
110 // release() is safe because parent will own it
111 return dlg.release();
112 }
113 return NULL;
114}
115
117{
119
121 {
122 return false;
123 }
124
126 S.mpEap = &eap;
127 bool bResult = VisitSettings( S );
128 wxASSERT_MSG( bResult, "You did not define DefineParameters() for this command" );
129 static_cast<void>(bResult); // fix unused variable warning in release mode
130
131 return eap.GetParameters(parms);
132}
133
134bool AudacityCommand::LoadSettingsFromString(const wxString & parms)
135{
136 wxString preset = parms;
137
138 CommandParameters eap(parms);
140
141 S.SetForWriting( &eap );
142 bool bResult = VisitSettings( S );
143 wxASSERT_MSG( bResult, "You did not define DefineParameters() for this command" );
144 static_cast<void>(bResult); // fix unused variable warning in release mode
145 if (!S.bOK)
146 {
148 XO(
149"%s: Could not load settings below. Default settings will be used.\n\n%s")
150 .Format( GetName(), preset ) );
151
152 // fror now always succeed, so that we can prompt the user.
153 return true;
154 }
155
156 return TransferDataToWindow();
157}
158
160 const CommandContext & context,
161 bool shouldPrompt /* = true */)
162{
163 // Note: Init may read parameters from preferences
164 if (!Init())
165 {
166 return false;
167 }
168
169 // Prompting will be bypassed when applying a command that has already
170 // been configured, e.g. repeating the last effect on a different selection.
171 // Prompting may call AudacityCommand::Preview
172 if (shouldPrompt && /*IsInteractive() && */!PromptUser(parent))
173 {
174 return false;
175 }
176
177 auto cleanup = finally( [&] {
178 End();
179 } );
180
181 bool returnVal = true;
182 bool skipFlag = CheckWhetherSkipAudacityCommand();
183 if (skipFlag == false)
184 {
185 auto name = GetName();
186 ProgressDialog progress{
187 name,
188 XO("Applying %s...").Format( name ),
190 };
191 auto vr = valueRestorer( mProgress, &progress );
192
193 returnVal = Apply(context);
194 }
195 return returnVal;
196}
197
198// This is used from Macros.
199bool AudacityCommand::PromptUser(wxWindow *parent)
200{
201 return ShowInterface(parent, IsBatchProcessing());
202}
203
205{
206 if (mUIParent && !mUIParent->TransferDataToWindow())
207 return false;
208 return true;
209}
210
212{
213 if (mUIParent && (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow()))
214 return false;
215 return true;
216}
217
219{
220 return false;
221}
222
224{
225 return false;
226}
227
229 const TranslatableString& message, long style,
230 const TranslatableString &titleStr)
231{
232 auto title = titleStr.empty()
233 ? GetName()
234 : XO("%s: %s").Format( GetName(), titleStr );
235 return AudacityMessageBox(message, title, style, mUIParent);
236}
237
238BEGIN_EVENT_TABLE(AudacityCommandDialog, wxDialogWrapper)
243
246 AudacityCommand * pCommand,
247 int type,
248 int flags,
249 int additionalButtons)
250: wxDialogWrapper(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, flags)
251{
252 mType = type;
253 wxASSERT( pCommand );
254 mpCommand = pCommand;
255 mAdditionalButtons = additionalButtons |eCancelButton;
256 if( !pCommand->ManualPage().empty() )
257 mAdditionalButtons |= eHelpButton;
258}
259
261{
262 ShuttleGui S(this, eIsCreating);
263
264 S.SetBorder(5);
265 S.StartVerticalLay(true);
266 {
268
269 long buttons = eOkButton;
270 S.AddStandardButtons(buttons|mAdditionalButtons);
271 }
272 S.EndVerticalLay();
273
274 Layout();
275 Fit();
276 SetMinSize(GetSize());
277 Center();
278 return true;
279}
280
285{
286 wxASSERT( mpCommand );
288}
289
291{
294 return true;
295}
296
298{
301 return true;
302}
303
305{
306 return true;
307}
308
309void AudacityCommandDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
310{
311 // On wxGTK (wx2.8.12), the default action is still executed even if
312 // the button is disabled. This appears to affect all wxDialogs, not
313 // just our AudacityCommands dialogs. So, this is a only temporary workaround
314 // for legacy effects that disable the OK button. Hopefully this has
315 // been corrected in wx3.
316 if (FindWindow(wxID_OK)->IsEnabled() && Validate() && TransferDataFromWindow())
317 {
318 EndModal(true);
319 }
320}
321
322
323void AudacityCommandDialog::OnCancel(wxCommandEvent & WXUNUSED(evt))
324{
325 EndModal(false);
326}
327
328void AudacityCommandDialog::OnHelp(wxCommandEvent & WXUNUSED(event))
329{
330 if( mpCommand )
331 {
332 // otherwise use ShowHelp
333 HelpSystem::ShowHelp(FindWindow(wxID_HELP), mpCommand->ManualPage(), true);
334 }
335}
336
337
#define BUILTIN_GENERIC_COMMAND_PREFIX
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
END_EVENT_TABLE()
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
const TranslatableString name
Definition: Distortion.cpp:74
XO("Cut/Copy/Paste")
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:234
#define safenew
Definition: MemoryX.h:10
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Definition: MemoryX.h:162
static const auto title
@ pdlgHideStopButton
EffectReverbSettings preset
Definition: Reverb.cpp:45
@ eIsSettingToDialog
Definition: ShuttleGui.h:41
@ eIsCreating
Definition: ShuttleGui.h:39
@ eIsGettingFromDialog
Definition: ShuttleGui.h:40
@ eOkButton
Definition: ShuttleGui.h:597
@ eCancelButton
Definition: ShuttleGui.h:598
@ eHelpButton
Definition: ShuttleGui.h:601
#define S(N)
Definition: ToChars.cpp:64
Default dialog used for commands. Is populated using ShuttleGui.
virtual void OnCancel(wxCommandEvent &evt)
AudacityCommand * mpCommand
bool Validate() override
virtual void OnHelp(wxCommandEvent &evt)
virtual void OnOk(wxCommandEvent &evt)
virtual void PopulateOrExchange(ShuttleGui &S)
bool TransferDataFromWindow() override
bool TransferDataToWindow() override
Base class for command in Audacity.
virtual bool IsBatchProcessing() const
wxDialog * mUIDialog
virtual bool Init()
virtual bool Apply(const CommandContext &WXUNUSED(context))
bool LoadSettingsFromString(const wxString &parms)
VendorSymbol GetVendor() const override
bool SaveSettingsAsString(wxString &parms)
virtual bool VisitSettings(SettingsVisitor &)
virtual ~AudacityCommand()
virtual void PopulateOrExchange(ShuttleGui &WXUNUSED(S))
virtual bool PromptUser(wxWindow *parent)
wxString GetVersion() const override
ComponentInterfaceSymbol GetSymbol() const override=0
wxWindow * mUIParent
virtual ManualPageID ManualPage()
bool ShowInterface(wxWindow *parent, bool forceModal=false)
virtual bool TransferDataFromWindow()
bool DoAudacityCommand(wxWindow *parent, const CommandContext &context, bool shouldPrompt=true)
virtual void End()
ProgressDialog * mProgress
PluginPath GetPath() const override
virtual bool TransferDataToWindow()
wxDialog * CreateUI(wxWindow *parent, AudacityCommand *client)
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
virtual bool CheckWhetherSkipAudacityCommand()
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
bool GetParameters(wxString &parms)
TranslatableString GetName() const
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
const wxString & Internal() const
Abstract base class used in importing a file.
static result_type Call(Arguments &&...arguments)
Null check of the installed function is done for you.
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:234
ProgressDialog Class.
Visitor of effect or command parameters. This is a base class with lots of virtual functions that do ...
Definition: Shuttle.h:115
SettingsVisitor that sets parameters to their default values.
SettingsVisitor that gets parameter values into a string.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:628
SettingsVisitor that sets parameters to a value (from a string)
Holds a msgid for the translation catalog; may also bind format arguments.