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/sizer.h>
32#include <wx/stockitem.h>
33#include <wx/string.h>
34#include <wx/tglbtn.h>
35#include <wx/timer.h>
36#include <wx/utils.h>
37#include <wx/log.h>
38
39#include "ConfigInterface.h"
40
41#include "../ShuttleAutomation.h"
42#include "../ShuttleGui.h"
43#include "../widgets/ProgressDialog.h"
44#include "../widgets/HelpSystem.h"
45#include "../widgets/AudacityMessageBox.h"
46#include "../widgets/VetoDialogHook.h"
47
48#include <unordered_map>
49
51{
52 mProgress = NULL;
53 mUIParent = NULL;
54 mUIDialog = NULL;
55 mIsBatch = false;
56 mNeedsInit = true;
57}
58
60{
61 if (mUIDialog)
62 mUIDialog->Close();
63}
64
65
67VendorSymbol AudacityCommand::GetVendor() const { return XO("Audacity");}
68wxString AudacityCommand::GetVersion() const { return AUDACITY_VERSION_STRING;}
69
70
72 if( !mNeedsInit )
73 return true;
74 mNeedsInit = false;
75 ShuttleDefaults DefaultSettingShuttle;
76 return VisitSettings( DefaultSettingShuttle );
77}
78
79bool AudacityCommand::ShowInterface(wxWindow *parent, bool WXUNUSED(forceModal))
80{
81 if (mUIDialog)
82 {
83 if ( mUIDialog->Close(true) )
84 mUIDialog = nullptr;
85 return false;
86 }
87
88 // mUIDialog is null
89 auto cleanup = valueRestorer( mUIDialog );
90
91 mUIDialog = CreateUI(parent, this);
92 if (!mUIDialog)
93 return false;
94
95 mUIDialog->Layout();
96 mUIDialog->Fit();
97 mUIDialog->SetMinSize(mUIDialog->GetSize());
98
99 // The Screenshot command might be popping this dialog up, just to capture it.
101 return false;
102
103 bool res = mUIDialog->ShowModal() != 0;
104 return res;
105}
106
107wxDialog *AudacityCommand::CreateUI(wxWindow *parent, AudacityCommand * WXUNUSED(client))
108{
110 parent, GetName(), this}};
111
112 if (dlg->Init())
113 {
114 // release() is safe because parent will own it
115 return dlg.release();
116 }
117 return NULL;
118}
119
121{
123
125 {
126 return false;
127 }
128
130 S.mpEap = &eap;
131 bool bResult = VisitSettings( S );
132 wxASSERT_MSG( bResult, "You did not define DefineParameters() for this command" );
133 static_cast<void>(bResult); // fix unused variable warning in release mode
134
135 return eap.GetParameters(parms);
136}
137
138bool AudacityCommand::LoadSettingsFromString(const wxString & parms)
139{
140 wxString preset = parms;
141
142 CommandParameters eap(parms);
144
145 S.SetForWriting( &eap );
146 bool bResult = VisitSettings( S );
147 wxASSERT_MSG( bResult, "You did not define DefineParameters() for this command" );
148 static_cast<void>(bResult); // fix unused variable warning in release mode
149 if (!S.bOK)
150 {
152 XO(
153"%s: Could not load settings below. Default settings will be used.\n\n%s")
154 .Format( GetName(), preset ) );
155
156 // fror now always succeed, so that we can prompt the user.
157 return true;
158 }
159
160 return TransferDataToWindow();
161}
162
164 const CommandContext & context,
165 bool shouldPrompt /* = true */)
166{
167 // Note: Init may read parameters from preferences
168 if (!Init())
169 {
170 return false;
171 }
172
173 // Prompting will be bypassed when applying a command that has already
174 // been configured, e.g. repeating the last effect on a different selection.
175 // Prompting may call AudacityCommand::Preview
176 if (shouldPrompt && /*IsInteractive() && */!PromptUser(parent))
177 {
178 return false;
179 }
180
181 auto cleanup = finally( [&] {
182 End();
183 } );
184
185 bool returnVal = true;
186 bool skipFlag = CheckWhetherSkipAudacityCommand();
187 if (skipFlag == false)
188 {
189 auto name = GetName();
190 ProgressDialog progress{
191 name,
192 XO("Applying %s...").Format( name ),
194 };
195 auto vr = valueRestorer( mProgress, &progress );
196
197 returnVal = Apply(context);
198 }
199 return returnVal;
200}
201
202// This is used from Macros.
203bool AudacityCommand::PromptUser(wxWindow *parent)
204{
205 return ShowInterface(parent, IsBatchProcessing());
206}
207
209{
210 if (mUIParent && !mUIParent->TransferDataToWindow())
211 return false;
212 return true;
213}
214
216{
217 if (mUIParent && (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow()))
218 return false;
219 return true;
220}
221
223{
224 return false;
225}
226
228{
229 return false;
230}
231
233 const TranslatableString& message, long style,
234 const TranslatableString &titleStr)
235{
236 auto title = titleStr.empty()
237 ? GetName()
238 : XO("%s: %s").Format( GetName(), titleStr );
239 return AudacityMessageBox(message, title, style, mUIParent);
240}
241
242BEGIN_EVENT_TABLE(AudacityCommandDialog, wxDialogWrapper)
247
250 AudacityCommand * pCommand,
251 int type,
252 int flags,
253 int additionalButtons)
254: wxDialogWrapper(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, flags)
255{
256 mType = type;
257 wxASSERT( pCommand );
258 mpCommand = pCommand;
259 mAdditionalButtons = additionalButtons |eCancelButton;
260 if( !pCommand->ManualPage().empty() )
261 mAdditionalButtons |= eHelpButton;
262}
263
265{
266 ShuttleGui S(this, eIsCreating);
267
268 S.SetBorder(5);
269 S.StartVerticalLay(true);
270 {
272
273 long buttons = eOkButton;
274 S.AddStandardButtons(buttons|mAdditionalButtons);
275 }
276 S.EndVerticalLay();
277
278 Layout();
279 Fit();
280 SetMinSize(GetSize());
281 Center();
282 return true;
283}
284
289{
290 wxASSERT( mpCommand );
292}
293
295{
298 return true;
299}
300
302{
305 return true;
306}
307
309{
310 return true;
311}
312
313void AudacityCommandDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
314{
315 // On wxGTK (wx2.8.12), the default action is still executed even if
316 // the button is disabled. This appears to affect all wxDialogs, not
317 // just our AudacityCommands dialogs. So, this is a only temporary workaround
318 // for legacy effects that disable the OK button. Hopefully this has
319 // been corrected in wx3.
320 if (FindWindow(wxID_OK)->IsEnabled() && Validate() && TransferDataFromWindow())
321 {
322 EndModal(true);
323 }
324}
325
326
327void AudacityCommandDialog::OnCancel(wxCommandEvent & WXUNUSED(evt))
328{
329 EndModal(false);
330}
331
332void AudacityCommandDialog::OnHelp(wxCommandEvent & WXUNUSED(event))
333{
334 if( mpCommand )
335 {
336 // otherwise use ShowHelp
337 HelpSystem::ShowHelp(FindWindow(wxID_HELP), mpCommand->ManualPage(), true);
338 }
339}
340
341
#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:82
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
#define XO(s)
Definition: Internat.h:31
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:226
#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:46
@ eIsSettingToDialog
Definition: ShuttleGui.h:41
@ eIsCreating
Definition: ShuttleGui.h:39
@ eIsGettingFromDialog
Definition: ShuttleGui.h:40
@ eOkButton
Definition: ShuttleGui.h:600
@ eCancelButton
Definition: ShuttleGui.h:601
@ eHelpButton
Definition: ShuttleGui.h:604
#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:237
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:631
SettingsVisitor that sets parameters to a value (from a string)
Holds a msgid for the translation catalog; may also bind format arguments.