Audacity 3.2.0
PluginMenus.cpp
Go to the documentation of this file.
1
2
3#include "../AudioIO.h"
4#include "../BatchProcessDialog.h"
5#include "../Benchmark.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 "../toolbars/ToolManager.h"
19#include "../Screenshot.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"
27#include "../effects/RealtimeEffectManager.h"
28#include "../prefs/EffectsPrefs.h"
29#include "../prefs/PrefsDialog.h"
30#include "../widgets/AudacityMessageBox.h"
31
32#include <wx/log.h>
33#include <wx/stdpaths.h>
34
35#include "XMLFileReader.h"
36
37// private helper classes and functions
38namespace {
39
40
41using EffectsMenuGroups = std::vector<std::pair<TranslatableString, std::vector<TranslatableString>>>;
42
44{
46 {
47 std::optional<std::string> textContent;
48 std::vector<TranslatableString>& effects;
49
50 EffectsHandler(std::vector<TranslatableString>& effects) : effects(effects) { }
51
52 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override { return true; }
53 void HandleXMLContent(const std::string_view& text) override { textContent = text; }
54 void HandleXMLEndTag(const std::string_view& tag) override
55 {
56 if(textContent.has_value() && tag == "Effect")
57 effects.emplace_back(TranslatableString { *textContent, {} });
58 textContent.reset();
59 }
60 XMLTagHandler* HandleXMLChild(const std::string_view& tag) override
61 {
62 if(tag == "Effect")
63 return this;
64 return nullptr;
65 }
66
67 };
68
70 {
71 std::optional<std::string> textContent;
72 std::unique_ptr<EffectsHandler> effectsHandler;
73 std::pair<TranslatableString, std::vector<TranslatableString>>& group;
74
75 GroupHandler(std::pair<TranslatableString, std::vector<TranslatableString>>& group) : group(group) { }
76
77 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override { return true; }
78 void HandleXMLContent(const std::string_view& text) override { textContent = text; }
79 void HandleXMLEndTag(const std::string_view& tag) override
80 {
81 if(textContent.has_value() && tag == "Name")
82 group.first = TranslatableString { *textContent, { } };
83 textContent.reset();
84 }
85 XMLTagHandler* HandleXMLChild(const std::string_view& tag) override
86 {
87 if(tag == "Effects")
88 {
89 effectsHandler = std::make_unique<EffectsHandler>(group.second);
90 return &*effectsHandler;
91 }
92 if(tag == "Name")
93 return this;
94
95 return nullptr;
96 }
97 };
98
100 std::unique_ptr<GroupHandler> groupHandler;
101
102 EffectsMenuGroupsHandler(EffectsMenuGroups& groups) : groups(groups) { }
103
104 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override { return true; }
105
106 XMLTagHandler* HandleXMLChild(const std::string_view& tag) override
107 {
108 if(tag == "Group")
109 {
110 groups.resize(groups.size() + 1);
111 groupHandler = std::make_unique<GroupHandler>(groups.back());
112 return &*groupHandler;
113 }
114 return nullptr;
115 }
116};
117
119{
120 EffectsMenuGroups result;
122
123 XMLFileReader reader;
124 reader.Parse(&handler, path);
125 return result;
126}
127
128enum class GroupBy
129{
130 Publisher,
131 Type
132};
133
134enum class SortBy
135{
136 Name,
139};
140
141// Some weird special case stuff just for Noise Reduction so that there is
142// more informative help
144{
145 if ( plug->GetSymbol().Msgid() == XO( "Noise Reduction" ) )
146 return ( batchflags | NoiseReductionTimeSelectedFlag() ) & ~TimeSelectedFlag();
147 return batchflags;
148}
149
150
152{
153 if( PluginManager::Get().IsPluginLoaded(plug->GetID()) && EffectManager::Get().IsHidden(plug->GetID()) )
154 return false;
155 if ( !plug->IsEnabled() ){
156 return false;// don't add to menus!
157 }
158 return true;
159}
160
162{
163 if (plug->IsEffectDefault()
164#ifdef EXPERIMENTAL_DA
165 // Move Nyquist prompt into nyquist group.
166 && (plug->GetSymbol() !=
167 ComponentInterfaceSymbol("Nyquist Effects Prompt"))
168 && (plug->GetSymbol() != ComponentInterfaceSymbol("Nyquist Tools Prompt"))
170#endif
171 )
172 return true;
173 return false;
174}
175
177{
178 if(IsDefaultPlugin(plug))
179 return true;
180 auto applicationResourcePath = wxFileName(FileNames::ResourcesDir());
181 auto pluginPath = wxFileName(plug->GetPath());
182 pluginPath.MakeAbsolute();
183 return pluginPath.GetPath().StartsWith(applicationResourcePath.GetPath());
184}
185
186auto MakeGroupsFilter(const EffectsMenuGroups& list) -> auto
187{
188 return [=](const PluginDescriptor* plug)
189 {
190 if(!IsEnabledPlugin(plug))
191 return false;
192
193 for(auto& p : list)
194 {
195 for(auto& name : p.second)
196 {
197 if(name == plug->GetSymbol().Msgid())
198 return true;
199 }
200 }
201 return false;
202 };
203}
204
205// Forward-declared function has its definition below with OnEffect in view
209 const PluginIDs & plugs,
210 const std::vector<CommandFlag> & flags,
211 bool useSubgroups);
212
213
216 std::vector<const PluginDescriptor*> & plugs,
217 CommandFlag batchflags,
218 CommandFlag realflags,
219 GroupBy groupBy,
220 bool useSubgroups)
221{
223 TranslatableString current;
224
225 size_t pluginCnt = plugs.size();
226
227 TranslatableStrings groupNames;
228 PluginIDs groupPlugs;
229 std::vector<CommandFlag> groupFlags;
230
231 for (size_t i = 0; i < pluginCnt; i++)
232 {
233 const PluginDescriptor *plug = plugs[i];
234
235 auto name = plug->GetSymbol().Msgid();
236
237 if (plug->IsEffectInteractive())
238 name += XO("...");
239
240 if (groupBy == GroupBy::Publisher/*wxT("groupby:publisher")*/)
241 {
242 current = EffectManager::Get().GetVendorName(plug->GetID());
243 if (current.empty())
244 {
245 current = XO("Unknown");
246 }
247 }
248 else if (groupBy == GroupBy::Type /*wxT("groupby:type")*/)
249 {
250 current = EffectManager::Get().GetEffectFamilyName(plug->GetID());
251 if (current.empty())
252 {
253 current = XO("Unknown");
254 }
255 }
256
257 if (current != last)
258 {
259 using namespace MenuTable;
260 BaseItemPtrs temp;
261 bool bInSubmenu = !last.empty() && (groupNames.size() > 1);
262
264 groupNames,
265 groupPlugs, groupFlags, useSubgroups);
266
267 table.push_back( MenuOrItems( wxEmptyString,
268 ( bInSubmenu ? last : TranslatableString{} ), std::move( temp )
269 ) );
270
271 groupNames.clear();
272 groupPlugs.clear();
273 groupFlags.clear();
274 last = current;
275 }
276
277 groupNames.push_back( name );
278 groupPlugs.push_back(plug->GetID());
279 groupFlags.push_back(FixBatchFlags( batchflags, plug ) );
280 }
281
282 if (groupNames.size() > 0)
283 {
284 using namespace MenuTable;
285 BaseItemPtrs temp;
286 bool bInSubmenu = groupNames.size() > 1;
287
289 groupNames, groupPlugs, groupFlags, useSubgroups);
290
291 table.push_back( MenuOrItems( wxEmptyString,
292 ( bInSubmenu ? current : TranslatableString{} ), std::move( temp )
293 ) );
294 }
295}
296
299 std::vector<const PluginDescriptor*> & plugs,
300 CommandFlag batchflags,
301 CommandFlag realflags,
302 SortBy sortBy,
303 bool useSubgroups)
304{
305 size_t pluginCnt = plugs.size();
306
307 TranslatableStrings groupNames;
308 PluginIDs groupPlugs;
309 std::vector<CommandFlag> groupFlags;
310
311 for (size_t i = 0; i < pluginCnt; i++)
312 {
313 const PluginDescriptor *plug = plugs[i];
314
315 auto name = plug->GetSymbol().Msgid();
316
317 if (plug->IsEffectInteractive())
318 name += XO("...");
319
320 TranslatableString group;
321 if (sortBy == SortBy::PublisherName/* wxT("sortby:publisher:name")*/)
322 {
323 group = EffectManager::Get().GetVendorName(plug->GetID());
324 }
325 else if (sortBy == SortBy::TypeName /*wxT("sortby:type:name")*/)
326 {
328 }
329
330 if (plug->IsEffectDefault())
331 {
332 group = {};
333 }
334
335 groupNames.push_back(
336 group.empty()
337 ? name
338 : XO("%s: %s").Format( group, name )
339 );
340
341 groupPlugs.push_back(plug->GetID());
342 groupFlags.push_back(FixBatchFlags( batchflags, plug ) );
343 }
344
345 if (groupNames.size() > 0)
346 {
348 table, groupNames, groupPlugs, groupFlags, useSubgroups);
349 }
350}
351
352auto MakeAddGroupItems(const EffectsMenuGroups& list, CommandFlag batchflags, CommandFlag realflags) -> auto
353{
354 return [=](MenuTable::BaseItemPtrs& items, std::vector<const PluginDescriptor*>& plugs)
355 {
356 for(auto& p : list)
357 {
358 TranslatableStrings groupNames;
359 PluginIDs groupPlugs;
360 std::vector<CommandFlag> groupFlags;
361
362 auto srcNames = p.second;
363 std::sort(srcNames.begin(), srcNames.end(), TranslationLess);
364
365 for(auto& name : srcNames)
366 {
367 auto it = std::find_if(plugs.begin(), plugs.end(), [&name](const PluginDescriptor* other)
368 {
369 return name == other->GetSymbol().Msgid();
370 });
371 if(it == plugs.end())
372 continue;
373
374 auto plug = *it;
375 if(plug->IsEffectInteractive())
376 groupNames.push_back(name + XO("..."));
377 else
378 groupNames.push_back( name );
379
380 groupPlugs.push_back(plug->GetID());
381 groupFlags.push_back(FixBatchFlags( batchflags, plug ) );
382 }
383
384 if (!groupNames.empty())
385 {
386 using namespace MenuTable;
387 BaseItemPtrs temp;
388
390 groupNames, groupPlugs, groupFlags, false);
391
392 items.push_back( MenuOrItems( wxEmptyString,
393 p.first, std::move( temp )
394 ) );
395 }
396 }
397 };
398}
399
401{
402 std::vector<const PluginDescriptor*> plugins;
403
404 std::function<bool(const PluginDescriptor*)> filter;
405 std::function<bool(const PluginDescriptor*, const PluginDescriptor*)> compare;
406 std::function<void(MenuTable::BaseItemPtrs&, std::vector<const PluginDescriptor*>&)> add;
407};
408
409AttachedWindows::RegisteredFactory sMacrosWindowKey{
410 []( AudacityProject &parent ) -> wxWeakRef< wxWindow > {
411 auto &window = ProjectWindow::Get( parent );
412 return safenew MacrosWindow(
413 &window, parent, true
414 );
415 }
416};
417
419 PluginManager &pm, wxWindow *parent)
420{
421 PluginRegistrationDialog dlg(parent);
422 return dlg.ShowModal() == wxID_OK;
423}
424
426{
427 auto &window = GetProjectFrame( project );
428 auto &pm = PluginManager::Get();
429 if (ShowManager(pm, &window))
431}
432
434{
435 auto &trackFocus = TrackFocus::Get(project);
436 auto &panel = RealtimeEffectPanel::Get(project);
437 if (panel.IsShown())
438 panel.HidePanel();
439 else
440 panel.ShowPanel(trackFocus.Get(), true);
441}
442
444{
445 return
446 std::make_pair( a->GetSymbol().Translation(), a->GetPath() ) <
447 std::make_pair( b->GetSymbol().Translation(), b->GetPath() );
448}
449
451 const PluginDescriptor *a, const PluginDescriptor *b)
452{
453 auto &em = EffectManager::Get();
454
455 auto akey = em.GetVendorName(a->GetID());
456 auto bkey = em.GetVendorName(b->GetID());
457
458 if (akey.empty())
459 akey = XO("Uncategorized");
460 if (bkey.empty())
461 bkey = XO("Uncategorized");
462
463 return
464 std::make_tuple(
465 akey.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
466 std::make_tuple(
467 bkey.Translation(), b->GetSymbol().Translation(), b->GetPath() );
468}
469
471 const PluginDescriptor *a, const PluginDescriptor *b)
472{
473 auto &em = EffectManager::Get();
474 auto akey = em.GetVendorName(a->GetID());
475 auto bkey = em.GetVendorName(b->GetID());
476
477 if (a->IsEffectDefault())
478 akey = {};
479 if (b->IsEffectDefault())
480 bkey = {};
481
482 return
483 std::make_tuple(
484 akey.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
485 std::make_tuple(
486 bkey.Translation(), b->GetSymbol().Translation(), b->GetPath() );
487}
488
490 const PluginDescriptor *a, const PluginDescriptor *b)
491{
492 auto &em = EffectManager::Get();
493 auto akey = em.GetEffectFamilyName(a->GetID());
494 auto bkey = em.GetEffectFamilyName(b->GetID());
495
496 if (akey.empty())
497 akey = XO("Uncategorized");
498 if (bkey.empty())
499 bkey = XO("Uncategorized");
500
501 if (a->IsEffectDefault())
502 akey = {};
503 if (b->IsEffectDefault())
504 bkey = {};
505
506 return
507 std::make_tuple(
508 akey.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
509 std::make_tuple(
510 bkey.Translation(), b->GetSymbol().Translation(), b->GetPath() );
511}
512
514{
515 auto &em = EffectManager::Get();
516 auto akey = em.GetEffectFamilyName(a->GetID());
517 auto bkey = em.GetEffectFamilyName(b->GetID());
518
519 if (akey.empty())
520 akey = XO("Uncategorized");
521 if (bkey.empty())
522 bkey = XO("Uncategorized");
523
524 return
525 std::make_tuple(
526 akey.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
527 std::make_tuple(
528 bkey.Translation(), b->GetSymbol().Translation(), b->GetPath() );
529}
530
535 EffectType type,
536 CommandFlag batchflags,
537 CommandFlag realflags)
538{
541
542 const auto groupby = EffectsGroupBy.Read();
543
544 std::vector<MenuSectionBuilder> sections;
545
546 auto MakeAddSortedItems = [=](SortBy sortby, bool useSubgroups)
547 {
548 return [=](MenuTable::BaseItemPtrs& items, std::vector<const PluginDescriptor*>& plugins)
549 {
550 return AddSortedEffectMenuItems(items, plugins, batchflags, realflags, sortby, useSubgroups);
551 };
552 };
553
554 auto MakeAddGroupedItems = [=](GroupBy groupBy, bool useSubgroups)
555 {
556 return [=](MenuTable::BaseItemPtrs& items, std::vector<const PluginDescriptor*>& plugins)
557 {
558 return AddGroupedEffectMenuItems(items, plugins, batchflags, realflags, groupBy, useSubgroups);
559 };
560 };
561
562 auto DefaultFilter = [](auto plug) { return IsEnabledPlugin(plug) && IsDefaultPlugin(plug); };
563 if(groupby == "default")
564 {
565 if(type == EffectTypeProcess)
566 {
567 static auto effectMenuDefaults = [] {
568 wxFileName path = wxFileName(FileNames::ResourcesDir(), wxT("EffectsMenuDefaults.xml"));
569 return LoadEffectsMenuGroups(path.GetFullPath());
570 }();
571 static auto groupsFilter = MakeGroupsFilter(effectMenuDefaults);
572
573 sections.emplace_back(
575 {},
576 [=](auto plug) { return IsEnabledPlugin(plug) && groupsFilter(plug); },
577 nullptr,
578 MakeAddGroupItems(effectMenuDefaults, batchflags, realflags)
579 });
580 sections.emplace_back(
582 {},
585 MakeAddGroupedItems(GroupBy::Publisher, false )
586 });
587 }
588 else//Generators/Analyzers
589 {
590 sections.emplace_back(
592 {},
593 [](auto plug){ return IsEnabledPlugin(plug) && IsBundledPlugin(plug); } ,
595 MakeAddSortedItems(SortBy::Name, false )
596 });
597 sections.emplace_back(
599 {},
602 MakeAddGroupedItems(GroupBy::Publisher, true )
603 });
604 }
605 }
606 else if(groupby == "sortby:publisher:name")
607 {
608 sections.emplace_back(
610 {},
611 DefaultFilter,
613 MakeAddSortedItems(SortBy::PublisherName, false)
614 });
615 sections.emplace_back(
617 {},
620 MakeAddSortedItems(SortBy::PublisherName, true )
621 });
622 }
623 else if(groupby == "sortby:type:name")
624 {
625 sections.emplace_back(
627 {},
628 DefaultFilter,
630 MakeAddSortedItems(SortBy::TypeName, false)
631 });
632 sections.emplace_back(
634 {},
637 MakeAddSortedItems(SortBy::TypeName, true )
638 });
639 }
640 else if(groupby == "groupby:publisher")
641 {
642 sections.emplace_back(
644 {},
645 DefaultFilter,
647 MakeAddGroupedItems(GroupBy::Publisher, false)
648 });
649 sections.emplace_back(
651 {},
654 MakeAddGroupedItems(GroupBy::Publisher, true )
655 });
656 }
657 else if(groupby == "groupby:type")
658 {
659 sections.emplace_back(
661 {},
662 DefaultFilter,
664 MakeAddGroupedItems(GroupBy::Type, false)
665 });
666 sections.emplace_back(
668 {},
671 MakeAddGroupedItems(GroupBy::Type, true )
672 });
673 }
674 else //if(groupby == "sortby:name")
675 {
676 sections.emplace_back(
678 {},
679 DefaultFilter,
681 MakeAddSortedItems(SortBy::Name, false)
682 });
683 sections.emplace_back(
685 {},
688 MakeAddSortedItems(SortBy::Name, true)
689 });
690 }
691 for(auto& plugin : pm.EffectsOfType(type))
692 {
693 for(auto& section : sections)
694 {
695 if(section.filter(&plugin))
696 {
697 section.plugins.push_back(&plugin);
698 break;
699 }
700 }
701 }
702
703 for(auto& section : sections)
704 {
705 if(section.compare != nullptr)
706 std::sort(section.plugins.begin(), section.plugins.end(), section.compare);
707
709 section.add(items, section.plugins);
710
711 if(items.empty())
712 continue;
713
714 if(result.empty())
715 result.push_back(MenuTable::Items( "", std::move( items ) ));
716 else
717 result.push_back(MenuTable::Section( "", std::move( items ) ));
718 }
719
720 return result;
721}
722
723// Forward-declared function has its definition below with OnApplyMacroDirectly
724// in view
726
727}
728
729namespace PluginActions {
730
731// Menu handler functions
732
734
735void OnResetConfig(const CommandContext &context)
736{
737 auto &project = context.project;
738 auto &menuManager = MenuManager::Get(project);
739 menuManager.mLastAnalyzerRegistration = MenuCreator::repeattypenone;
740 menuManager.mLastToolRegistration = MenuCreator::repeattypenone;
741 menuManager.mLastGenerator = "";
742 menuManager.mLastEffect = "";
743 menuManager.mLastAnalyzer = "";
744 menuManager.mLastTool = "";
745
747
748 // Directory will be reset on next restart.
749 FileNames::UpdateDefaultPath(FileNames::Operation::Temp, TempDirectory::DefaultTempDir());
750
751 // There are many more things we could reset here.
752 // Beeds discussion as to which make sense to.
753 // Maybe in future versions?
754 // - Reset Effects
755 // - Reset Recording and Playback volumes
756 // - Reset Selection formats (and for spectral too)
757 // - Reset Play-at-speed speed to x1
758 // - Stop playback/recording and unapply pause.
759 // - Set Zoom sensibly.
760 gPrefs->Write("/GUI/SyncLockTracks", 0);
761 gPrefs->Write("/AudioIO/SoundActivatedRecord", 0);
762 gPrefs->Write("/SelectionToolbarMode", 0);
763 gPrefs->Flush();
764 DoReloadPreferences(project);
765
768
769 // These are necessary to preserve the newly correctly laid out toolbars.
770 // In particular the Device Toolbar ends up short on next restart,
771 // if they are left out.
772 gPrefs->Write(wxT("/PrefsVersion"), wxString(wxT(AUDACITY_PREFS_VERSION_STRING)));
773
774 // write out the version numbers to the prefs file for future checking
775 gPrefs->Write(wxT("/Version/Major"), AUDACITY_VERSION);
776 gPrefs->Write(wxT("/Version/Minor"), AUDACITY_RELEASE);
777 gPrefs->Write(wxT("/Version/Micro"), AUDACITY_REVISION);
778
779 gPrefs->Flush();
780
782 .AS_SetSnapTo(gPrefs->ReadLong("/SnapTo", SNAP_OFF));
784 .AS_SetRate(gPrefs->ReadDouble("/DefaultProjectSampleRate", 44100.0));
785}
786
788{
789 auto &project = context.project;
790 DoManagePluginsMenu(project);
791}
792
793void OnEffect(const CommandContext &context)
794{
795 // using GET to interpret parameter as a PluginID
796 EffectUI::DoEffect(context.parameter.GET(), context, 0);
797}
798
799void OnManageEffects(const CommandContext &context)
800{
801 auto &project = context.project;
802 DoManagePluginsMenu(project);
803}
804
806{
807 auto& project = context.project;
809}
810
811void OnAnalyzer2(wxCommandEvent& evt) { return; }
812
814{
815 auto& menuManager = MenuManager::Get(context.project);
816 auto lastEffect = menuManager.mLastGenerator;
817 if (!lastEffect.empty())
818 {
820 lastEffect, context, menuManager.mRepeatGeneratorFlags | EffectManager::kRepeatGen);
821 }
822}
823
825{
826 auto& menuManager = MenuManager::Get(context.project);
827 auto lastEffect = menuManager.mLastEffect;
828 if (!lastEffect.empty())
829 {
831 lastEffect, context, menuManager.mRepeatEffectFlags);
832 }
833}
834
836{
837 auto& menuManager = MenuManager::Get(context.project);
838 switch (menuManager.mLastAnalyzerRegistration) {
840 {
841 auto lastEffect = menuManager.mLastAnalyzer;
842 if (!lastEffect.empty())
843 {
845 lastEffect, context, menuManager.mRepeatAnalyzerFlags);
846 }
847 }
848 break;
851 menuManager.mLastAnalyzerRegisteredId);
852 break;
853 }
854}
855
857{
858 auto& menuManager = MenuManager::Get(context.project);
859 switch (menuManager.mLastToolRegistration) {
861 {
862 auto lastEffect = menuManager.mLastTool;
863 if (!lastEffect.empty())
864 {
866 lastEffect, context, menuManager.mRepeatToolFlags);
867 }
868 }
869 break;
872 menuManager.mLastToolRegisteredId);
873 break;
875 OnApplyMacroDirectlyByName(context, menuManager.mLastTool);
876 break;
877 }
878}
879
880
882{
883 auto &project = context.project;
884 DoManagePluginsMenu(project);
885}
886
887void OnManageTools(const CommandContext &context )
888{
889 auto &project = context.project;
890 DoManagePluginsMenu(project);
891}
892
893void OnManageMacros(const CommandContext &context )
894{
895 auto &project = context.project;
896 CommandManager::Get(project).RegisterLastTool(context); //Register Macros as Last Tool
897 auto macrosWindow = &GetAttachedWindows(project)
898 .AttachedWindows::Get< MacrosWindow >( sMacrosWindowKey );
899 if (macrosWindow) {
900 macrosWindow->Show();
901 macrosWindow->Raise();
902 macrosWindow->UpdateDisplay( true );
903 }
904}
905
907{
908 auto &project = context.project;
909 CommandManager::Get(project).RegisterLastTool(context); //Register Palette as Last Tool
910 auto macrosWindow = &GetAttachedWindows(project)
911 .AttachedWindows::Get< MacrosWindow >( sMacrosWindowKey );
912 if (macrosWindow) {
913 macrosWindow->Show();
914 macrosWindow->Raise();
915 macrosWindow->UpdateDisplay( false );
916 }
917}
918
919void OnScreenshot(const CommandContext &context )
920{
921 CommandManager::Get(context.project).RegisterLastTool(context); //Register Screenshot as Last Tool
923}
924
925void OnBenchmark(const CommandContext &context)
926{
927 auto &project = context.project;
928 CommandManager::Get(project).RegisterLastTool(context); //Register Run Benchmark as Last Tool
929 auto &window = GetProjectFrame( project );
930 ::RunBenchmark( &window, project);
931}
932
934{
935 auto &project = context.project;
936 auto &commandManager = CommandManager::Get( project );
937
938 auto gAudioIO = AudioIO::Get();
939 bool &setting = gAudioIO->mSimulateRecordingErrors;
940 commandManager.Check(wxT("SimulateRecordingErrors"), !setting);
941 setting = !setting;
942}
943
945{
946 auto &project = context.project;
947 auto &commandManager = CommandManager::Get( project );
948
949 auto gAudioIO = AudioIO::Get();
950 auto &setting = gAudioIO->mDetectUpstreamDropouts;
951 auto oldValue = setting.load(std::memory_order_relaxed);
952 commandManager.Check(wxT("DetectUpstreamDropouts"), !oldValue);
953 setting.store(!oldValue, std::memory_order_relaxed);
954}
955
957{
958 auto OnMessage =
959 /* i18n-hint a "journal" is a text file that records
960 the user's interactions with the application */
961 XO("A journal will be recorded after Audacity restarts.");
962 auto OffMessage =
963 /* i18n-hint a "journal" is a text file that records
964 the user's interactions with the application */
965 XO("No journal will be recorded after Audacity restarts.");
966
967 using namespace Journal;
968 bool enabled = RecordEnabled();
969 if ( SetRecordEnabled(!enabled) )
970 enabled = !enabled;
971 if ( enabled )
972 AudacityMessageBox( OnMessage );
973 else
974 AudacityMessageBox( OffMessage );
975}
976
978{
979 const MacroID& Name = context.parameter.GET();
980 OnApplyMacroDirectlyByName(context, Name);
981}
982void OnApplyMacroDirectlyByName(const CommandContext& context, const MacroID& Name)
983{
984 auto &project = context.project;
985 auto &window = ProjectWindow::Get( project );
986 //wxLogDebug( "Macro was: %s", context.parameter);
987 ApplyMacroDialog dlg( &window, project );
988 //const auto &Name = context.parameter;
989
990// We used numbers previously, but macros could get renumbered, making
991// macros containing macros unpredictable.
992#ifdef MACROS_BY_NUMBERS
993 long item=0;
994 // Take last three letters (of e.g. Macro007) and convert to a number.
995 Name.Mid( Name.length() - 3 ).ToLong( &item, 10 );
996 dlg.ApplyMacroToProject( item, false );
997#else
998 dlg.ApplyMacroToProject( Name, false );
999#endif
1000 /* i18n-hint: %s will be the name of the macro which will be
1001 * repeated if this menu item is chosen */
1003
1006 auto shortDesc = em.GetCommandName(Name);
1007 auto& undoManager = UndoManager::Get(project);
1008 auto& commandManager = CommandManager::Get(project);
1009 int cur = undoManager.GetCurrentState();
1010 if (undoManager.UndoAvailable()) {
1011 undoManager.GetShortDescription(cur, &desc);
1012 commandManager.Modify(wxT("RepeatLastTool"), XXO("&Repeat %s")
1013 .Format(desc));
1014 auto& menuManager = MenuManager::Get(project);
1015 menuManager.mLastTool = Name;
1016 menuManager.mLastToolRegistration = MenuCreator::repeattypeapplymacro;
1017 }
1018
1019}
1020
1022{
1023 // using GET in a log message for devs' eyes only
1024 wxLogDebug( "Command was: %s", ctx.parameter.GET());
1025 // Not configured, so prompt user.
1027 EffectManager::Get().GetEffectByIdentifier(ctx.parameter),
1029}
1030
1031}; // struct Handler
1032
1033} // namespace
1034
1036 // Handler is not stateful. Doesn't need a factory registered with
1037 // AudacityProject.
1038 static PluginActions::Handler instance;
1039 return instance;
1040};
1041
1042// Menu definitions? ...
1043
1044#define FN(X) (& PluginActions::Handler :: X)
1045
1046// ... buf first some more helper definitions, which use FN
1047namespace {
1048
1051 const TranslatableStrings & names,
1052 const PluginIDs & plugs,
1053 const std::vector<CommandFlag> & flags,
1054 bool useSubgroups)
1055{
1056 const int namesCnt = (int) names.size();
1057 int perGroup;
1058
1059#if defined(__WXGTK__)
1060 gPrefs->Read(wxT("/Effects/MaxPerGroup"), &perGroup, 15);
1061#else
1062 gPrefs->Read(wxT("/Effects/MaxPerGroup"), &perGroup, 0);
1063#endif
1064
1065 int groupCnt = namesCnt;
1066 for (int i = 0; i < namesCnt; i++)
1067 {
1068 // compare full translations not msgids!
1069 while (i + 1 < namesCnt && names[i].Translation() == names[i + 1].Translation())
1070 {
1071 i++;
1072 groupCnt--;
1073 }
1074 }
1075
1076 if (namesCnt > 0 && !useSubgroups)
1077 {
1078 perGroup = 0;
1079 }
1080
1081 int max = perGroup;
1082 int items = perGroup;
1083
1084 if (max > groupCnt)
1085 {
1086 max = 0;
1087 }
1088
1089 using namespace MenuTable;
1090 // This finder scope may be redundant, but harmless
1092 auto pTable = &table;
1093 BaseItemPtrs temp1;
1094
1095 int groupNdx = 0;
1096 for (int i = 0; i < namesCnt; i++)
1097 {
1098 if (max > 0 && items == max)
1099 {
1100 // start collecting items for the next submenu
1101 pTable = &temp1;
1102 }
1103
1104 // compare full translations not msgids!
1105 if (i + 1 < namesCnt && names[i].Translation() == names[i + 1].Translation())
1106 {
1107 // collect a sub-menu for like-named items
1108 const auto name = names[i];
1109 const auto translation = name.Translation();
1110 BaseItemPtrs temp2;
1111 // compare full translations not msgids!
1112 while (i < namesCnt && names[i].Translation() == translation)
1113 {
1114 const PluginDescriptor *plug =
1115 PluginManager::Get().GetPlugin(plugs[i]);
1116 if( plug->GetPluginType() == PluginTypeEffect )
1117 temp2.push_back( Command( plug->GetID(),
1118 Verbatim( plug->GetPath() ),
1119 FN(OnEffect),
1120 flags[i],
1122 .IsEffect()
1123 .AllowInMacros()
1124 .Parameter( plugs[i] ) ) );
1125
1126 i++;
1127 }
1128 pTable->push_back( Menu( wxEmptyString, name, std::move( temp2 ) ) );
1129 i--;
1130 }
1131 else
1132 {
1133 // collect one item
1134 const PluginDescriptor *plug =
1135 PluginManager::Get().GetPlugin(plugs[i]);
1136 if( plug->GetPluginType() == PluginTypeEffect )
1137 pTable->push_back( Command(
1138 plug->GetID(),
1139 names[i],
1140 FN(OnEffect),
1141 flags[i],
1143 .IsEffect()
1144 .AllowInMacros()
1145 .Parameter( plugs[i] ) ) );
1146 }
1147
1148 if (max > 0)
1149 {
1150 items--;
1151 if (items == 0 || i + 1 == namesCnt)
1152 {
1153 int end = groupNdx + max;
1154 if (end + 1 > groupCnt)
1155 {
1156 end = groupCnt;
1157 }
1158 // Done collecting
1159 table.push_back( Menu( wxEmptyString,
1160 XXO("Plugin %d to %d").Format( groupNdx + 1, end ),
1161 std::move( temp1 )
1162 ) );
1163 items = max;
1164 pTable = &table;
1165 groupNdx += max;
1166 }
1167 }
1168 }
1169}
1170
1172{
1174 auto names = MacroCommands::GetNames(); // these names come from filenames
1175 int i;
1176
1177 // This finder scope may be redundant, but harmless
1179 for (i = 0; i < (int)names.size(); i++) {
1181 result.push_back( MenuTable::Command( MacroID,
1182 Verbatim( names[i] ), // file name verbatim
1183 FN(OnApplyMacroDirectly),
1184 flags,
1186 ) );
1187 }
1188
1189 return result;
1190}
1191
1192}
1193
1194// Menu definitions
1195
1196// Under /MenuBar
1197namespace {
1198using namespace MenuTable;
1199
1202 [](const AudacityProject &project){
1203 return !MenuManager::Get( project ).mLastGenerator.empty();
1204 }
1205 }; return flag; }
1206
1208{
1209 // All of this is a bit hacky until we can get more things connected into
1210 // the plugin manager...sorry! :-(
1211
1213
1214 static BaseItemSharedPtr menu{
1216 Menu( wxT("Generate"), XXO("&Generate"),
1217 Section( "Manage",
1218 Command( wxT("ManageGenerators"), XXO("Plugin Manager"),
1219 FN(OnManageGenerators), AudioIONotBusyFlag() )
1220 ),
1221
1222 Section("RepeatLast",
1223 // Delayed evaluation:
1224 [](AudacityProject &project)
1225 {
1226 const auto &lastGenerator = MenuManager::Get(project).mLastGenerator;
1227 TranslatableString buildMenuLabel;
1228 if (!lastGenerator.empty())
1229 buildMenuLabel = XO("Repeat %s")
1230 .Format(EffectManager::Get().GetCommandName(lastGenerator));
1231 else
1232 buildMenuLabel = XO("Repeat Last Generator");
1233
1234 return Command(wxT("RepeatLastGenerator"), buildMenuLabel,
1235 FN(OnRepeatLastGenerator),
1238 Options{}.IsGlobal(), findCommandHandler);
1239 }
1240 ),
1241
1242 Section( "Generators",
1243 // Delayed evaluation:
1244 [](AudacityProject &)
1245 { return Items( wxEmptyString, PopulateEffectsMenu(
1249 ); }
1250 )
1251 ) ) };
1252 return menu;
1253}
1254
1255static const ReservedCommandFlag
1257 [](const AudacityProject &project){
1258 return !RealtimeEffectManager::Get(project).IsActive();
1259 }
1260}; return flag; } //lll
1261
1263 wxT(""),
1264 Shared( GenerateMenu() )
1265};
1266
1269 [](const AudacityProject &project) {
1270 return !MenuManager::Get(project).mLastEffect.empty();
1271 }
1272 }; return flag;
1273}
1274
1275static const ReservedCommandFlag&
1277 [](const AudacityProject &project) {
1278 auto& trackFocus = TrackFocus::Get(const_cast<AudacityProject&>(project));
1279 return (trackFocus.Get() != nullptr);
1280 }
1281 };
1282 return flag;
1283}
1284
1286{
1287 // All of this is a bit hacky until we can get more things connected into
1288 // the plugin manager...sorry! :-(
1289
1290 static BaseItemSharedPtr menu{
1292 Menu( wxT("Effect"), XXO("Effe&ct"),
1293 Section( "Manage",
1294 Command( wxT("ManageEffects"), XXO("Plugin Manager"),
1295 FN(OnManageEffects), AudioIONotBusyFlag() )
1296 ),
1297
1298 Section( "RealtimeEffects",
1299 Command ( wxT("AddRealtimeEffects"), XXO("Add Realtime Effects"),
1300 FN(OnAddRealtimeEffects), HasTrackFocusFlag(), wxT("E") )
1301 ),
1302
1303 Section( "RepeatLast",
1304 // Delayed evaluation:
1305 [](AudacityProject &project)
1306 {
1307 const auto &lastEffect = MenuManager::Get(project).mLastEffect;
1308 TranslatableString buildMenuLabel;
1309 if (!lastEffect.empty())
1310 buildMenuLabel = XO("Repeat %s")
1311 .Format( EffectManager::Get().GetCommandName(lastEffect) );
1312 else
1313 buildMenuLabel = XO("Repeat Last Effect");
1314
1315 return Command( wxT("RepeatLastEffect"), buildMenuLabel,
1316 FN(OnRepeatLastEffect),
1319 wxT("Ctrl+R"), findCommandHandler );
1320 }
1321 ),
1322
1323 Section( "Effects",
1324 // Delayed evaluation:
1325 [](AudacityProject &)
1326 { return Items( wxEmptyString, PopulateEffectsMenu(
1330 ); }
1331 )
1332 ) ) };
1333 return menu;
1334}
1335
1337 wxT(""),
1338 Shared( EffectMenu() )
1339};
1340
1343 [](const AudacityProject &project) {
1345 return !MenuManager::Get(project).mLastAnalyzer.empty();
1346 }
1347 }; return flag;
1348}
1349
1351{
1352 // All of this is a bit hacky until we can get more things connected into
1353 // the plugin manager...sorry! :-(
1354
1356
1357 static BaseItemSharedPtr menu{
1359 Menu( wxT("Analyze"), XXO("&Analyze"),
1360 Section( "Manage",
1361 Command( wxT("ManageAnalyzers"), XXO("Plugin Manager"),
1362 FN(OnManageAnalyzers), AudioIONotBusyFlag() )
1363 ),
1364
1365 Section("RepeatLast",
1366 // Delayed evaluation:
1367 [](AudacityProject &project)
1368 {
1369 const auto &lastAnalyzer = MenuManager::Get(project).mLastAnalyzer;
1370 TranslatableString buildMenuLabel;
1371 if (!lastAnalyzer.empty())
1372 buildMenuLabel = XO("Repeat %s")
1373 .Format(EffectManager::Get().GetCommandName(lastAnalyzer));
1374 else
1375 buildMenuLabel = XO("Repeat Last Analyzer");
1376
1377 return Command(wxT("RepeatLastAnalyzer"), buildMenuLabel,
1378 FN(OnRepeatLastAnalyzer),
1381 Options{}.IsGlobal(), findCommandHandler);
1382 }
1383 ),
1384
1385 Section( "Analyzers",
1386 Items( "Windows" ),
1387
1388 // Delayed evaluation:
1389 [](AudacityProject&)
1390 { return Items( wxEmptyString, PopulateEffectsMenu(
1394 ); }
1395 )
1396 ) ) };
1397 return menu;
1398}
1399
1401 wxT(""),
1402 Shared( AnalyzeMenu() )
1403};
1404
1407 [](const AudacityProject &project) {
1408 auto& menuManager = MenuManager::Get(project);
1409 if (menuManager.mLastToolRegistration == MenuCreator::repeattypeunique) return true;
1410 return !menuManager.mLastTool.empty();
1411 }
1412 }; return flag;
1413}
1414
1416{
1418
1419 static BaseItemSharedPtr menu{
1421 Menu( wxT("Tools"), XXO("T&ools"),
1422 Section( "Manage",
1423 Command( wxT("ManageTools"), XXO("Plugin Manager"),
1424 FN(OnManageTools), AudioIONotBusyFlag() ),
1425
1426 //Separator(),
1427
1428 Section( "RepeatLast",
1429 // Delayed evaluation:
1430 [](AudacityProject &project)
1431 {
1432 const auto &lastTool = MenuManager::Get(project).mLastTool;
1433 TranslatableString buildMenuLabel;
1434 if (!lastTool.empty())
1435 buildMenuLabel = XO("Repeat %s")
1436 .Format( EffectManager::Get().GetCommandName(lastTool) );
1437 else
1438 buildMenuLabel = XO("Repeat Last Tool");
1439
1440 return Command( wxT("RepeatLastTool"), buildMenuLabel,
1441 FN(OnRepeatLastTool),
1444 Options{}.IsGlobal(), findCommandHandler );
1445 }
1446 ),
1447
1448 Command( wxT("ManageMacros"), XXO("&Macro Manager"),
1449 FN(OnManageMacros), AudioIONotBusyFlag() ),
1450
1451 Menu( wxT("Macros"), XXO("&Apply Macro"),
1452 // Palette has no access key to ensure first letter navigation of
1453 // sub menu
1454 Section( "",
1455 Command( wxT("ApplyMacrosPalette"), XXO("Palette..."),
1456 FN(OnApplyMacrosPalette), AudioIONotBusyFlag() )
1457 ),
1458
1459 Section( "",
1460 // Delayed evaluation:
1461 [](AudacityProject&)
1462 { return Items( wxEmptyString, PopulateMacrosMenu( AudioIONotBusyFlag() ) ); }
1463 )
1464 )
1465 ),
1466
1467 Section( "Other",
1468 Command( wxT("ConfigReset"), XXO("Reset &Configuration"),
1469 FN(OnResetConfig),
1471
1472 Command( wxT("FancyScreenshot"), XXO("&Screenshot..."),
1473 FN(OnScreenshot), AudioIONotBusyFlag() ),
1474
1475 // PRL: team consensus for 2.2.0 was, we let end users have this diagnostic,
1476 // as they used to in 1.3.x
1477 //#ifdef IS_ALPHA
1478 // TODO: What should we do here? Make benchmark a plug-in?
1479 // Easy enough to do. We'd call it mod-self-test.
1480 Command( wxT("Benchmark"), XXO("&Run Benchmark..."),
1481 FN(OnBenchmark), AudioIONotBusyFlag() )
1482 //#endif
1483 ),
1484
1485 Section( "Tools",
1486 // Delayed evaluation:
1487 [](AudacityProject&)
1488 { return Items( wxEmptyString, PopulateEffectsMenu(
1492 ); }
1493 )
1494
1495#ifdef IS_ALPHA
1496 ,
1497 Section( "",
1498 Command( wxT("SimulateRecordingErrors"),
1499 XXO("Simulate Recording Errors"),
1500 FN(OnSimulateRecordingErrors),
1502 Options{}.CheckTest(
1503 [](AudacityProject&){
1504 return AudioIO::Get()->mSimulateRecordingErrors; } ) ),
1505 Command( wxT("DetectUpstreamDropouts"),
1506 XXO("Detect Upstream Dropouts"),
1507 FN(OnDetectUpstreamDropouts),
1509 Options{}.CheckTest(
1510 [](AudacityProject&){
1512 .load(std::memory_order_relaxed); } ) )
1513 )
1514#endif
1515
1516#if defined(IS_ALPHA) || defined(END_USER_JOURNALLING)
1517 ,
1518 Section( "",
1519 Command( wxT("WriteJournal"),
1520 /* i18n-hint a "journal" is a text file that records
1521 the user's interactions with the application */
1522 XXO("Write Journal"),
1523 FN(OnWriteJournal),
1525 Options{}.CheckTest( [](AudacityProject&){
1526 return Journal::RecordEnabled(); } ) )
1527 )
1528#endif
1529
1530 ) ) };
1531 return menu;
1532}
1533
1535 wxT(""),
1536 Shared( ToolsMenu() )
1537};
1538
1540{
1541 // These are the more useful to VI user Scriptables.
1542 static BaseItemSharedPtr menu{
1544 // i18n-hint: Scriptables are commands normally used from Python, Perl etc.
1545 Menu( wxT("Scriptables1"), XXO("Script&ables I"),
1546 // Note that the PLUGIN_SYMBOL must have a space between words,
1547 // whereas the short-form used here must not.
1548 // (So if you did write "CompareAudio" for the PLUGIN_SYMBOL name, then
1549 // you would have to use "Compareaudio" here.)
1550 Command( wxT("SelectTime"), XXO("Select Time..."), FN(OnAudacityCommand),
1552 Command( wxT("SelectFrequencies"), XXO("Select Frequencies..."),
1553 FN(OnAudacityCommand),
1555 Command( wxT("SelectTracks"), XXO("Select Tracks..."),
1556 FN(OnAudacityCommand),
1558 Command( wxT("SetTrackStatus"), XXO("Set Track Status..."),
1559 FN(OnAudacityCommand),
1561 Command( wxT("SetTrackAudio"), XXO("Set Track Audio..."),
1562 FN(OnAudacityCommand),
1564 Command( wxT("SetTrackVisuals"), XXO("Set Track Visuals..."),
1565 FN(OnAudacityCommand),
1567 Command( wxT("GetPreference"), XXO("Get Preference..."),
1568 FN(OnAudacityCommand),
1570 Command( wxT("SetPreference"), XXO("Set Preference..."),
1571 FN(OnAudacityCommand),
1573 Command( wxT("SetClip"), XXO("Set Clip..."), FN(OnAudacityCommand),
1575 Command( wxT("SetEnvelope"), XXO("Set Envelope..."),
1576 FN(OnAudacityCommand),
1578 Command( wxT("SetLabel"), XXO("Set Label..."), FN(OnAudacityCommand),
1580 Command( wxT("SetProject"), XXO("Set Project..."), FN(OnAudacityCommand),
1582 ) ) };
1583 return menu;
1584}
1585
1587 wxT("Optional/Extra/Part2"),
1589};
1590
1592{
1593 // Less useful to VI users.
1594 static BaseItemSharedPtr menu{
1596 // i18n-hint: Scriptables are commands normally used from Python, Perl etc.
1597 Menu( wxT("Scriptables2"), XXO("Scripta&bles II"),
1598 Command( wxT("Select"), XXO("Select..."), FN(OnAudacityCommand),
1600 Command( wxT("SetTrack"), XXO("Set Track..."), FN(OnAudacityCommand),
1602 Command( wxT("GetInfo"), XXO("Get Info..."), FN(OnAudacityCommand),
1604 Command( wxT("Message"), XXO("Message..."), FN(OnAudacityCommand),
1606 Command( wxT("Help"), XXO("Help..."), FN(OnAudacityCommand),
1608 Command( wxT("Import2"), XXO("Import..."), FN(OnAudacityCommand),
1610 Command( wxT("Export2"), XXO("Export..."), FN(OnAudacityCommand),
1612 Command( wxT("OpenProject2"), XXO("Open Project..."),
1613 FN(OnAudacityCommand),
1615 Command( wxT("SaveProject2"), XXO("Save Project..."),
1616 FN(OnAudacityCommand),
1618 Command( wxT("Drag"), XXO("Move Mouse..."), FN(OnAudacityCommand),
1620 Command( wxT("CompareAudio"), XXO("Compare Audio..."),
1621 FN(OnAudacityCommand),
1623 // i18n-hint: Screenshot in the help menu has a much bigger dialog.
1624 Command( wxT("Screenshot"), XXO("Screenshot (short format)..."),
1625 FN(OnAudacityCommand),
1627 ) ) };
1628 return menu;
1629}
1630
1632 wxT("Optional/Extra/Part2"),
1634};
1635
1636}
1637
1638#undef FN
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
void RunBenchmark(wxWindow *parent, AudacityProject &project)
Definition: Benchmark.cpp:95
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
std::bitset< NCommandFlags > CommandFlag
Definition: CommandFlag.h:31
wxEvtHandler CommandHandlerObject
const ReservedCommandFlag & NoiseReductionTimeSelectedFlag()
const ReservedCommandFlag & AudioIONotBusyFlag()
const ReservedCommandFlag & TimeSelectedFlag()
const ReservedCommandFlag & WaveTracksSelectedFlag()
static TransactionScope::Factory::Scope scope
const TranslatableString name
Definition: Distortion.cpp:82
EffectType
@ EffectTypeAnalyze
@ EffectTypeGenerate
@ EffectTypeTool
@ EffectTypeProcess
ChoiceSetting EffectsGroupBy
const TranslatableString desc
Definition: ExportPCM.cpp:58
#define XXO(s)
Definition: Internat.h:44
#define XO(s)
Definition: Internat.h:31
#define safenew
Definition: MemoryX.h:10
wxString MacroID
Definition: Menus.h:33
wxArrayString PluginIDs
Definition: Menus.h:34
@ PluginTypeEffect
#define NYQUIST_PROMPT_ID
static CommandHandlerObject & findCommandHandler(AudacityProject &)
#define FN(X)
FileConfig * gPrefs
Definition: Prefs.cpp:71
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 ...
AUDACITY_DLL_API AttachedWindows & GetAttachedWindows(AudacityProject &project)
void OpenScreenshotTools(AudacityProject &project)
Definition: Screenshot.cpp:135
static TranslatableStrings names
Definition: TagsEditor.cpp:151
bool TranslationLess(const TranslatableString &a, const TranslatableString &b)
A commonly needed sort comparator, which depends on the language setting.
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
static std::once_flag flag
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
Shows progress in executing commands in MacroCommands.
void ApplyMacroToProject(int iMacro, bool bHasGui=true)
static CommandID MacroIdOfName(const wxString &MacroName)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
static AudioIO * Get()
Definition: AudioIO.cpp:133
bool mSimulateRecordingErrors
Definition: AudioIO.h:378
std::atomic< bool > mDetectUpstreamDropouts
Definition: AudioIO.h:382
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)
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
const TranslatableString & Msgid() const
const wxString Translation() const
EffectManager is the class that handles effects and effect categories.
Definition: EffectManager.h:48
static EffectManager & Get()
TranslatableString GetCommandName(const PluginID &ID)
TranslatableString GetVendorName(const PluginID &ID)
TranslatableString GetEffectFamilyName(const PluginID &ID)
bool IsHidden(const PluginID &ID)
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
Abstract base class used in importing a file.
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 wxArrayString GetNames()
static bool DoAudacityCommand(const PluginID &ID, const CommandContext &context, unsigned flags)
void UpdateDisplay(bool bExpanded)
static void RebuildAllMenuBars()
Definition: Menus.cpp:687
PluginID mLastAnalyzer
Definition: Menus.h:54
int mLastAnalyzerRegistration
Definition: Menus.h:55
@ repeattypeplugin
Definition: Menus.h:62
@ repeattypeapplymacro
Definition: Menus.h:64
@ repeattypenone
Definition: Menus.h:61
@ repeattypeunique
Definition: Menus.h:63
PluginID mLastGenerator
Definition: Menus.h:52
PluginID mLastTool
Definition: Menus.h:57
PluginID mLastEffect
Definition: Menus.h:53
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:71
static void ModifyUndoMenuItems(AudacityProject &project)
Definition: Menus.cpp:444
const ComponentInterfaceSymbol & GetSymbol() const
PluginType GetPluginType() const
bool IsEffectDefault() const
bool IsEffectInteractive() const
const wxString & GetID() const
bool IsEnabled() const
const PluginPath & GetPath() const
PluginManager maintains a list of all plug ins. That covers modules, effects, generators,...
Definition: PluginManager.h:42
Range EffectsOfType(EffectType type)
const PluginDescriptor * GetPlugin(const PluginID &ID) const
static PluginManager & Get()
void AS_SetSnapTo(int snap) override
static ProjectSelectionManager & Get(AudacityProject &project)
void AS_SetRate(double rate) override
static ProjectWindow & Get(AudacityProject &project)
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)
static void OnResetToolBars(const CommandContext &context)
Track * Get()
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:67
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:19
bool Parse(XMLTagHandler *baseHandler, const FilePath &fname)
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
AUDACITY_DLL_API bool DoEffect(const PluginID &ID, const CommandContext &context, unsigned flags)
'Repeat Last Effect'.
Definition: EffectUI.cpp:1240
FILES_API FilePath ResourcesDir()
FILES_API void UpdateDefaultPath(Operation op, const FilePath &path)
Facilities for recording and playback of sequences of user interaction.
bool RecordEnabled()
Definition: Journal.cpp:204
bool SetRecordEnabled(bool value)
Definition: Journal.cpp:209
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())
BaseItemPtr MenuOrItems(const Identifier &internalName, const TranslatableString &title, Args &&... args)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
std::vector< BaseItemPtr > BaseItemPtrs
Definition: Registry.h:73
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:72
FILES_API const FilePath & DefaultTempDir()
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:535
MenuTable::BaseItemPtrs PopulateEffectsMenu(EffectType type, CommandFlag batchflags, CommandFlag realflags)
bool IsEnabledPlugin(const PluginDescriptor *plug)
const ReservedCommandFlag & HasLastToolFlag()
const ReservedCommandFlag & HasLastEffectFlag()
bool CompareEffectsByType(const PluginDescriptor *a, const PluginDescriptor *b)
CommandFlag FixBatchFlags(CommandFlag batchflags, const PluginDescriptor *plug)
bool CompareEffectsByName(const PluginDescriptor *a, const PluginDescriptor *b)
AttachedWindows::RegisteredFactory sMacrosWindowKey
const ReservedCommandFlag & HasLastAnalyzerFlag()
bool CompareEffectsByPublisherAndName(const PluginDescriptor *a, const PluginDescriptor *b)
static const ReservedCommandFlag & HasTrackFocusFlag()
void DoManagePluginsMenu(AudacityProject &project)
bool ShowManager(PluginManager &pm, wxWindow *parent)
bool CompareEffectsByTypeAndName(const PluginDescriptor *a, const PluginDescriptor *b)
void DoManageRealtimeEffectsSidePanel(AudacityProject &project)
EffectsMenuGroups LoadEffectsMenuGroups(const wxString &path)
void AddSortedEffectMenuItems(MenuTable::BaseItemPtrs &table, std::vector< const PluginDescriptor * > &plugs, CommandFlag batchflags, CommandFlag realflags, SortBy sortBy, bool useSubgroups)
auto MakeGroupsFilter(const EffectsMenuGroups &list) -> auto
static const ReservedCommandFlag & IsRealtimeNotActiveFlag()
void AddEffectMenuItemGroup(MenuTable::BaseItemPtrs &table, const TranslatableStrings &names, const PluginIDs &plugs, const std::vector< CommandFlag > &flags, bool useSubgroups)
bool IsBundledPlugin(const PluginDescriptor *plug)
bool IsDefaultPlugin(const PluginDescriptor *plug)
auto MakeAddGroupItems(const EffectsMenuGroups &list, CommandFlag batchflags, CommandFlag realflags) -> auto
bool CompareEffectsByPublisher(const PluginDescriptor *a, const PluginDescriptor *b)
BaseItemSharedPtr ExtraScriptablesIIMenu()
std::vector< std::pair< TranslatableString, std::vector< TranslatableString > > > EffectsMenuGroups
Definition: PluginMenus.cpp:41
BaseItemSharedPtr ExtraScriptablesIMenu()
const ReservedCommandFlag & HasLastGeneratorFlag()
void AddGroupedEffectMenuItems(MenuTable::BaseItemPtrs &table, std::vector< const PluginDescriptor * > &plugs, CommandFlag batchflags, CommandFlag realflags, GroupBy groupBy, bool useSubgroups)
MenuTable::BaseItemPtrs PopulateMacrosMenu(CommandFlag flags)
Options && IsEffect(bool value=true) &&
Options && AllowInMacros(int value=1) &&
void OnManageAnalyzers(const CommandContext &context)
void OnRepeatLastTool(const CommandContext &context)
void OnApplyMacroDirectlyByName(const CommandContext &context, const MacroID &Name)
void OnRepeatLastGenerator(const CommandContext &context)
void OnScreenshot(const CommandContext &context)
void OnAudacityCommand(const CommandContext &ctx)
void OnResetConfig(const CommandContext &context)
void OnManageMacros(const CommandContext &context)
void OnAddRealtimeEffects(const CommandContext &context)
void OnManageTools(const CommandContext &context)
void OnApplyMacrosPalette(const CommandContext &context)
void OnAnalyzer2(wxCommandEvent &evt)
void OnDetectUpstreamDropouts(const CommandContext &context)
void OnSimulateRecordingErrors(const CommandContext &context)
void OnApplyMacroDirectly(const CommandContext &context)
void OnRepeatLastAnalyzer(const CommandContext &context)
void OnManageEffects(const CommandContext &context)
void OnBenchmark(const CommandContext &context)
void OnManageGenerators(const CommandContext &context)
void OnRepeatLastEffect(const CommandContext &context)
void OnEffect(const CommandContext &context)
void OnWriteJournal(const CommandContext &)
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
Definition: PluginMenus.cpp:52
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
Definition: PluginMenus.cpp:60
GroupHandler(std::pair< TranslatableString, std::vector< TranslatableString > > &group)
Definition: PluginMenus.cpp:75
std::pair< TranslatableString, std::vector< TranslatableString > > & group
Definition: PluginMenus.cpp:73
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
Definition: PluginMenus.cpp:77
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
Definition: PluginMenus.cpp:85
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
std::function< bool(const PluginDescriptor *)> filter
std::vector< const PluginDescriptor * > plugins
std::function< void(MenuTable::BaseItemPtrs &, std::vector< const PluginDescriptor * > &)> add
std::function< bool(const PluginDescriptor *, const PluginDescriptor *)> compare