Audacity 3.2.0
PluginMenus.cpp
Go to the documentation of this file.
1
2
3#include "AudioIO.h"
4#include "../Benchmark.h"
5#include "../commands/CommandDispatch.h"
6#include "../CommonCommandFlags.h"
7#include "Journal.h"
8#include "../Menus.h"
9#include "PluginManager.h"
10#include "../PluginRegistrationDialog.h"
11#include "Prefs.h"
12#include "Project.h"
13#include "../ProjectSettings.h"
14#include "../ProjectWindow.h"
15#include "../ProjectWindows.h"
16#include "../ProjectSelectionManager.h"
17#include "RealtimeEffectPanel.h"
18#include "SyncLock.h"
19#include "../toolbars/ToolManager.h"
20#include "../TrackPanelAx.h"
21#include "TempDirectory.h"
22#include "UndoManager.h"
23#include "../commands/CommandContext.h"
24#include "../commands/CommandManager.h"
25#include "../effects/EffectManager.h"
26#include "../effects/EffectUI.h"
28#include "../prefs/PrefsDialog.h"
29#include "AudacityMessageBox.h"
30#include "MenuHelper.h"
31#include "prefs/EffectsPrefs.h"
32
33
34// private helper classes and functions
35namespace {
36
38 PluginManager &pm, wxWindow *parent)
39{
40 PluginRegistrationDialog dlg(parent);
41 return dlg.ShowModal() == wxID_OK;
42}
43
45{
46 auto &window = GetProjectFrame( project );
47 auto &pm = PluginManager::Get();
48 if (ShowManager(pm, &window))
50}
51
53{
54 auto &trackFocus = TrackFocus::Get(project);
55 auto &panel = RealtimeEffectPanel::Get(project);
56 if (panel.IsShown())
57 panel.HidePanel();
58 else
59 panel.ShowPanel(trackFocus.Get(), true);
60}
61
62
63}
64
65namespace {
66
67// Menu handler functions
68
69void OnResetConfig(const CommandContext &context)
70{
71 auto &project = context.project;
72 auto &menuManager = MenuManager::Get(project);
73 menuManager.mLastAnalyzerRegistration = MenuCreator::repeattypenone;
74 menuManager.mLastToolRegistration = MenuCreator::repeattypenone;
75 menuManager.mLastGenerator = "";
76 menuManager.mLastEffect = "";
77 menuManager.mLastAnalyzer = "";
78 menuManager.mLastTool = "";
79
81
82 // Directory will be reset on next restart.
84
85 // There are many more things we could reset here.
86 // Beeds discussion as to which make sense to.
87 // Maybe in future versions?
88 // - Reset Effects
89 // - Reset Recording and Playback volumes
90 // - Reset Selection formats (and for spectral too)
91 // - Reset Play-at-speed speed to x1
92 // - Stop playback/recording and unapply pause.
93 // - Set Zoom sensibly.
96 gPrefs->Write("/SelectionToolbarMode", 0);
97 gPrefs->Flush();
98 DoReloadPreferences(project);
99
102
103 // These are necessary to preserve the newly correctly laid out toolbars.
104 // In particular the Device Toolbar ends up short on next restart,
105 // if they are left out.
106 gPrefs->Write(wxT("/PrefsVersion"), wxString(wxT(AUDACITY_PREFS_VERSION_STRING)));
107
108 // write out the version numbers to the prefs file for future checking
109 gPrefs->Write(wxT("/Version/Major"), AUDACITY_VERSION);
110 gPrefs->Write(wxT("/Version/Minor"), AUDACITY_RELEASE);
111 gPrefs->Write(wxT("/Version/Micro"), AUDACITY_REVISION);
112
113 gPrefs->Flush();
114
116 .AS_SetSnapTo(gPrefs->ReadLong("/SnapTo", SNAP_OFF));
118 .AS_SetRate(gPrefs->ReadDouble("/DefaultProjectSampleRate", 44100.0));
119}
120
122{
123 auto &project = context.project;
124 DoManagePluginsMenu(project);
125}
126
127void OnEffect(const CommandContext &context)
128{
129 // using GET to interpret parameter as a PluginID
130 EffectUI::DoEffect(context.parameter.GET(), context, 0);
131}
132
133void OnManageEffects(const CommandContext &context)
134{
135 auto &project = context.project;
136 DoManagePluginsMenu(project);
137}
138
140{
141 auto& project = context.project;
143}
144
145void OnAnalyzer2(wxCommandEvent& evt) { return; }
146
148{
149 auto& menuManager = MenuManager::Get(context.project);
150 auto lastEffect = menuManager.mLastGenerator;
151 if (!lastEffect.empty())
152 {
154 lastEffect, context, menuManager.mRepeatGeneratorFlags | EffectManager::kRepeatGen);
155 }
156}
157
159{
160 auto& menuManager = MenuManager::Get(context.project);
161 auto lastEffect = menuManager.mLastEffect;
162 if (!lastEffect.empty())
163 {
165 lastEffect, context, menuManager.mRepeatEffectFlags);
166 }
167}
168
170{
171 auto& menuManager = MenuManager::Get(context.project);
172 switch (menuManager.mLastAnalyzerRegistration) {
174 {
175 auto lastEffect = menuManager.mLastAnalyzer;
176 if (!lastEffect.empty())
177 {
179 lastEffect, context, menuManager.mRepeatAnalyzerFlags);
180 }
181 }
182 break;
185 menuManager.mLastAnalyzerRegisteredId);
186 break;
187 }
188}
189
191{
192 auto &project = context.project;
193 DoManagePluginsMenu(project);
194}
195
196void OnManageTools(const CommandContext &context )
197{
198 auto &project = context.project;
199 DoManagePluginsMenu(project);
200}
201
202void OnBenchmark(const CommandContext &context)
203{
204 auto &project = context.project;
205 CommandManager::Get(project).RegisterLastTool(context); //Register Run Benchmark as Last Tool
206 auto &window = GetProjectFrame( project );
207 ::RunBenchmark( &window, project);
208}
209
211{
212 auto &project = context.project;
213 auto &commandManager = CommandManager::Get( project );
214
215 auto gAudioIO = AudioIO::Get();
216 bool &setting = gAudioIO->mSimulateRecordingErrors;
217 commandManager.Check(wxT("SimulateRecordingErrors"), !setting);
218 setting = !setting;
219}
220
222{
223 auto &project = context.project;
224 auto &commandManager = CommandManager::Get( project );
225
226 auto gAudioIO = AudioIO::Get();
227 auto &setting = gAudioIO->mDetectUpstreamDropouts;
228 auto oldValue = setting.load(std::memory_order_relaxed);
229 commandManager.Check(wxT("DetectUpstreamDropouts"), !oldValue);
230 setting.store(!oldValue, std::memory_order_relaxed);
231}
232
234{
235 auto OnMessage =
236 /* i18n-hint a "journal" is a text file that records
237 the user's interactions with the application */
238 XO("A journal will be recorded after Audacity restarts.");
239 auto OffMessage =
240 /* i18n-hint a "journal" is a text file that records
241 the user's interactions with the application */
242 XO("No journal will be recorded after Audacity restarts.");
243
244 using namespace Journal;
245 bool enabled = RecordEnabled();
246 if ( SetRecordEnabled(!enabled) )
247 enabled = !enabled;
248 if ( enabled )
249 AudacityMessageBox( OnMessage );
250 else
251 AudacityMessageBox( OffMessage );
252}
253
254}
255
256// Menu definitions
257
258// Under /MenuBar
259using namespace MenuTable;
260
261namespace {
264 [](const AudacityProject &project){
265 return !MenuManager::Get( project ).mLastGenerator.empty();
266 }
267 }; return flag; }
268
270{
271 // All of this is a bit hacky until we can get more things connected into
272 // the plugin manager...sorry! :-(
273
275
276 static BaseItemSharedPtr menu{
277 Menu( wxT("Generate"), XXO("&Generate"),
278 Section( "Manage",
279 Command( wxT("ManageGenerators"), XXO("Plugin Manager"),
281 ),
282
283 Section("RepeatLast",
284 // Delayed evaluation:
285 [](AudacityProject &project)
286 {
287 const auto &lastGenerator = MenuManager::Get(project).mLastGenerator;
288 TranslatableString buildMenuLabel;
289 if (!lastGenerator.empty())
290 buildMenuLabel = XO("Repeat %s")
291 .Format(EffectManager::Get().GetCommandName(lastGenerator));
292 else
293 buildMenuLabel = XO("Repeat Last Generator");
294
295 return Command(wxT("RepeatLastGenerator"), buildMenuLabel,
299 Options{}.IsGlobal());
300 }
301 ),
302
303 Section( "Generators",
304 // Delayed evaluation:
305 [](AudacityProject &)
306 { return Items( wxEmptyString, MenuHelper::PopulateEffectsMenu(
310 &OnEffect)
311 ); }
312 )
313 ) };
314 return menu;
315}
316
317static const ReservedCommandFlag
319 [](const AudacityProject &project){
320 return !RealtimeEffectManager::Get(project).IsActive();
321 }
322}; return flag; } //lll
323
325 wxT(""),
327};
328
331 [](const AudacityProject &project) {
332 return !MenuManager::Get(project).mLastEffect.empty();
333 }
334 }; return flag;
335}
336
337static const ReservedCommandFlag&
339 [](const AudacityProject &project) {
340 auto& trackFocus = TrackFocus::Get(const_cast<AudacityProject&>(project));
341 return (trackFocus.Get() != nullptr);
342 }
343 };
344 return flag;
345}
346
348{
349 // All of this is a bit hacky until we can get more things connected into
350 // the plugin manager...sorry! :-(
351
352 static BaseItemSharedPtr menu{
353 Menu( wxT("Effect"), XXO("Effe&ct"),
354 Section( "Manage",
355 Command( wxT("ManageEffects"), XXO("Plugin Manager"),
357 ),
358
359 Section( "RealtimeEffects",
360 Command ( wxT("AddRealtimeEffects"), XXO("Add Realtime Effects"),
362 ),
363
364 Section( "RepeatLast",
365 // Delayed evaluation:
366 [](AudacityProject &project)
367 {
368 const auto &lastEffect = MenuManager::Get(project).mLastEffect;
369 TranslatableString buildMenuLabel;
370 if (!lastEffect.empty())
371 buildMenuLabel = XO("Repeat %s")
372 .Format( EffectManager::Get().GetCommandName(lastEffect) );
373 else
374 buildMenuLabel = XO("Repeat Last Effect");
375
376 return Command( wxT("RepeatLastEffect"), buildMenuLabel,
380 wxT("Ctrl+R") );
381 }
382 ),
383
384 Section( "Effects",
385 // Delayed evaluation:
386 [](AudacityProject &)
387 { return Items( wxEmptyString, MenuHelper::PopulateEffectsMenu(
391 &OnEffect)
392 ); }
393 )
394 ) };
395 return menu;
396}
397
399 wxT(""),
400 Shared( EffectMenu() )
401};
402
405 [](const AudacityProject &project) {
407 return !MenuManager::Get(project).mLastAnalyzer.empty();
408 }
409 }; return flag;
410}
411
413{
414 // All of this is a bit hacky until we can get more things connected into
415 // the plugin manager...sorry! :-(
416
418
419 static BaseItemSharedPtr menu{
420 Menu( wxT("Analyze"), XXO("&Analyze"),
421 Section( "Manage",
422 Command( wxT("ManageAnalyzers"), XXO("Plugin Manager"),
424 ),
425
426 Section("RepeatLast",
427 // Delayed evaluation:
428 [](AudacityProject &project)
429 {
430 const auto &lastAnalyzer = MenuManager::Get(project).mLastAnalyzer;
431 TranslatableString buildMenuLabel;
432 if (!lastAnalyzer.empty())
433 buildMenuLabel = XO("Repeat %s")
434 .Format(EffectManager::Get().GetCommandName(lastAnalyzer));
435 else
436 buildMenuLabel = XO("Repeat Last Analyzer");
437
438 return Command(wxT("RepeatLastAnalyzer"), buildMenuLabel,
442 Options{}.IsGlobal());
443 }
444 ),
445
446 Section( "Analyzers",
447 Items( "Windows" ),
448
449 // Delayed evaluation:
450 [](AudacityProject&)
451 { return Items( wxEmptyString, MenuHelper::PopulateEffectsMenu(
455 &OnEffect)
456 ); }
457 )
458 ) };
459 return menu;
460}
461
463 wxT(""),
465};
466
468{
470
471 static BaseItemSharedPtr menu{
472 Menu( wxT("Tools"), XXO("T&ools"),
473 Section( "Manage",
474 Command( wxT("ManageTools"), XXO("Plugin Manager"),
476
477 //Separator(),
478 ),
479
480 Section( "Other",
481 Command( wxT("ConfigReset"), XXO("Reset &Configuration"),
484
485 // PRL: team consensus for 2.2.0 was, we let end users have this diagnostic,
486 // as they used to in 1.3.x
487 //#ifdef IS_ALPHA
488 // TODO: What should we do here? Make benchmark a plug-in?
489 // Easy enough to do. We'd call it mod-self-test.
490 Command( wxT("Benchmark"), XXO("&Run Benchmark..."),
492 //#endif
493 ),
494
495 Section( "Tools",
496 // Delayed evaluation:
497 [](AudacityProject&)
498 { return Items( wxEmptyString, MenuHelper::PopulateEffectsMenu(
502 OnEffect)
503 ); }
504 )
505
506#ifdef IS_ALPHA
507 ,
508 Section( "",
509 Command( wxT("SimulateRecordingErrors"),
510 XXO("Simulate Recording Errors"),
514 [](AudacityProject&){
515 return AudioIO::Get()->mSimulateRecordingErrors; } ) ),
516 Command( wxT("DetectUpstreamDropouts"),
517 XXO("Detect Upstream Dropouts"),
521 [](AudacityProject&){
523 .load(std::memory_order_relaxed); } ) )
524 )
525#endif
526
527#if defined(IS_ALPHA) || defined(END_USER_JOURNALLING)
528 ,
529 Section( "",
530 Command( wxT("WriteJournal"),
531 /* i18n-hint a "journal" is a text file that records
532 the user's interactions with the application */
533 XXO("Write Journal"),
537 return Journal::RecordEnabled(); } ) )
538 )
539#endif
540
541 ) };
542 return menu;
543}
544
546 wxT(""),
547 Shared( ToolsMenu() )
548};
549
550}
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
BoolSetting SoundActivatedRecord
Definition: AudioIO.cpp:3333
AttachedItem sAttachment1
AttachedItem sAttachment3
AttachedItem sAttachment2
void RunBenchmark(wxWindow *parent, AudacityProject &project)
Definition: Benchmark.cpp:89
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:34
const ReservedCommandFlag & AudioIONotBusyFlag()
const ReservedCommandFlag & TimeSelectedFlag()
const ReservedCommandFlag & WaveTracksSelectedFlag()
@ EffectTypeAnalyze
@ EffectTypeGenerate
@ EffectTypeTool
@ EffectTypeProcess
ChoiceSetting EffectsGroupBy
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
FileConfig * gPrefs
Definition: Prefs.cpp:70
void ResetPreferences()
Call this to reset preferences to an (almost)-"new" default state.
Definition: Prefs.cpp:208
#define AUDACITY_PREFS_VERSION_STRING
Definition: Prefs.h:39
void DoReloadPreferences(AudacityProject &project)
@ SNAP_OFF
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
BoolSetting SyncLockTracks
Definition: SyncLock.cpp:172
static std::once_flag flag
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static AudioIO * Get()
Definition: AudioIO.cpp:147
bool mSimulateRecordingErrors
Definition: AudioIO.h:403
std::atomic< bool > mDetectUpstreamDropouts
Definition: AudioIO.h:407
wxString Read() const
Definition: Prefs.cpp:354
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
CommandParameter parameter
AudacityProject & project
void RegisterLastTool(const CommandContext &context)
void DoRepeatProcess(const CommandContext &context, int)
static CommandManager & Get(AudacityProject &project)
static EffectManager & Get()
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
const wxString & GET() const
Explicit conversion to wxString, meant to be ugly-looking and demanding of a comment why it's correct...
Definition: Identifier.h:66
static void RebuildAllMenuBars()
Definition: Menus.cpp:621
PluginID mLastAnalyzer
Definition: Menus.h:53
@ repeattypeplugin
Definition: Menus.h:61
@ repeattypenone
Definition: Menus.h:60
@ repeattypeunique
Definition: Menus.h:62
int mLastAnalyzerRegistration
Definition: Menus.h:54
PluginID mLastGenerator
Definition: Menus.h:51
PluginID mLastEffect
Definition: Menus.h:52
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:69
PluginManager maintains a list of all plug ins. That covers modules, effects, generators,...
Definition: PluginManager.h:47
static PluginManager & Get()
void AS_SetSnapTo(int snap) override
static ProjectSelectionManager & Get(AudacityProject &project)
void AS_SetRate(double rate) override
static void OnResetWindow(const CommandContext &context)
static RealtimeEffectManager & Get(AudacityProject &project)
bool IsActive() const noexcept
To be called only from main thread.
static RealtimeEffectPanel & Get(AudacityProject &project)
bool Reset()
Reset to the default value.
Definition: Prefs.h:277
static void OnResetToolBars(const CommandContext &context)
Track * Get()
Holds a msgid for the translation catalog; may also bind format arguments.
AUDACITY_DLL_API bool DoEffect(const PluginID &ID, const CommandContext &context, unsigned flags)
'Repeat Last Effect'.
Definition: EffectUI.cpp:1263
FILES_API void UpdateDefaultPath(Operation op, const FilePath &path)
Facilities for recording and playback of sequences of user interaction.
bool SetRecordEnabled(bool value)
Definition: Journal.cpp:209
bool RecordEnabled()
Definition: Journal.cpp:204
MenuTable::BaseItemPtrs PopulateEffectsMenu(EffectType type, CommandFlag batchflags, const wxString &groupby, void(*onMenuCommand)(const CommandContext &), std::function< bool(const PluginDescriptor &)> pred={})
Definition: MenuHelper.cpp:558
std::unique_ptr< MenuItem > Menu(const Identifier &internalName, const TranslatableString &title, Args &&... args)
std::unique_ptr< MenuPart > Section(const Identifier &internalName, Args &&... args)
std::unique_ptr< MenuItems > Items(const Identifier &internalName, Args &&... args)
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:72
FILES_API const FilePath & DefaultTempDir()
void OnRepeatLastEffect(const CommandContext &context)
void OnWriteJournal(const CommandContext &)
const ReservedCommandFlag & HasLastEffectFlag()
void OnResetConfig(const CommandContext &context)
Definition: PluginMenus.cpp:69
const ReservedCommandFlag & HasLastAnalyzerFlag()
static const ReservedCommandFlag & HasTrackFocusFlag()
void DoManagePluginsMenu(AudacityProject &project)
Definition: PluginMenus.cpp:44
void OnAnalyzer2(wxCommandEvent &evt)
bool ShowManager(PluginManager &pm, wxWindow *parent)
Definition: PluginMenus.cpp:37
void OnRepeatLastGenerator(const CommandContext &context)
void DoManageRealtimeEffectsSidePanel(AudacityProject &project)
Definition: PluginMenus.cpp:52
void OnRepeatLastAnalyzer(const CommandContext &context)
void OnEffect(const CommandContext &context)
static const ReservedCommandFlag & IsRealtimeNotActiveFlag()
void OnManageTools(const CommandContext &context)
void OnDetectUpstreamDropouts(const CommandContext &context)
void OnBenchmark(const CommandContext &context)
void OnManageEffects(const CommandContext &context)
void OnManageAnalyzers(const CommandContext &context)
void OnSimulateRecordingErrors(const CommandContext &context)
const ReservedCommandFlag & HasLastGeneratorFlag()
void OnAddRealtimeEffects(const CommandContext &context)
void OnManageGenerators(const CommandContext &context)
Options && CheckTest(const CheckFn &fn) &&
Options && IsGlobal() &&