Audacity  3.0.3
PluginManager.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  PluginManager.cpp
6 
7  Leland Lucius
8 
9 *******************************************************************/
22 #include "PluginManager.h"
23 
24 
25 
26 #include <algorithm>
27 
28 #include <wx/log.h>
29 #include <wx/tokenzr.h>
30 
31 #include "ModuleInterface.h"
32 
33 #include "AudacityFileConfig.h"
34 #include "Internat.h" // for macro XO
35 #include "FileNames.h"
36 #include "MemoryX.h"
37 #include "ModuleManager.h"
38 #include "PlatformCompatibility.h"
40 
42 //
43 // Plugindescriptor
44 //
46 
48 {
50  mEnabled = false;
51  mValid = false;
52  mInstance = nullptr;
53 
55  mEffectInteractive = false;
56  mEffectDefault = false;
57  mEffectLegacy = false;
58  mEffectRealtime = false;
59  mEffectAutomatable = false;
60 }
61 
63 {
64 }
65 
67 
69 {
70  return mInstance != nullptr;
71 }
72 
74 {
75  if (!mInstance)
76  {
79  else
80  {
82  mInstance = muInstance.get();
83  }
84  }
85 
86  return mInstance;
87 }
88 
89 void PluginDescriptor::SetInstance(std::unique_ptr<ComponentInterface> instance)
90 {
91  muInstance = std::move(instance);
92  mInstance = muInstance.get();
93 }
94 
96 {
97  return mPluginType;
98 }
99 
101 {
102  return mID;
103 }
104 
106 {
107  return mProviderID;
108 }
109 
111 {
112  return mPath;
113 }
114 
116 {
117  return mSymbol;
118 }
119 
121 {
122  return mVersion;
123 }
124 
126 {
127  return mVendor;
128 }
129 
131 {
132  return mEnabled;
133 }
134 
136 {
137  return mValid;
138 }
139 
141 {
142  mPluginType = type;
143 }
144 
146 {
147  mID = ID;
148 }
149 
151 {
152  mProviderID = providerID;
153 }
154 
156 {
157  mPath = path;
158 }
159 
161 {
162  mSymbol = symbol;
163 }
164 
165 void PluginDescriptor::SetVersion(const wxString & version)
166 {
167  mVersion = version;
168 }
169 
170 void PluginDescriptor::SetVendor(const wxString & vendor)
171 {
172  mVendor = vendor;
173 }
174 
176 {
177  mEnabled = enable;
178 }
179 
181 {
182  mValid = valid;
183 }
184 
185 // Effects
186 
188 {
189  return mEffectFamily;
190 }
191 
193 {
194  return mEffectType;
195 }
196 
198 {
199  return mEffectInteractive;
200 }
201 
203 {
204  return mEffectDefault;
205 }
206 
208 {
209  return mEffectLegacy;
210 }
211 
213 {
214  return mEffectRealtime;
215 }
216 
218 {
219  return mEffectAutomatable;
220 }
221 
222 void PluginDescriptor::SetEffectFamily(const wxString & family)
223 {
224  mEffectFamily = family;
225 }
226 
228 {
229  mEffectType = type;
230 }
231 
233 {
234  mEffectInteractive = interactive;
235 }
236 
238 {
239  mEffectDefault = dflt;
240 }
241 
243 {
244  mEffectLegacy = legacy;
245 }
246 
248 {
249  mEffectRealtime = realtime;
250 }
251 
253 {
254  mEffectAutomatable = automatable;
255 }
256 
257 // Importer
258 
260 {
261  return mImporterIdentifier;
262 }
263 
264 void PluginDescriptor::SetImporterIdentifier(const wxString & identifier)
265 {
266  mImporterIdentifier = identifier;
267 }
268 
270  const
271 {
272  return mImporterExtensions;
273 }
274 
276 {
277  mImporterExtensions = std::move( extensions );
278 }
279 
281 //
282 // PluginManager
283 //
285 
286 // Registry has the list of plug ins
287 #define REGVERKEY wxString(wxT("/pluginregistryversion"))
288 #define REGVERCUR wxString(wxT("1.1"))
289 #define REGROOT wxString(wxT("/pluginregistry/"))
290 
291 // Settings has the values of the plug in settings.
292 #define SETVERKEY wxString(wxT("/pluginsettingsversion"))
293 #define SETVERCUR wxString(wxT("1.0"))
294 #define SETROOT wxString(wxT("/pluginsettings/"))
295 
296 #define KEY_ID wxT("ID")
297 #define KEY_PATH wxT("Path")
298 #define KEY_SYMBOL wxT("Symbol")
299 #define KEY_NAME wxT("Name")
300 #define KEY_VENDOR wxT("Vendor")
301 #define KEY_VERSION wxT("Version")
302 #define KEY_DESCRIPTION wxT("Description")
303 #define KEY_LASTUPDATED wxT("LastUpdated")
304 #define KEY_ENABLED wxT("Enabled")
305 #define KEY_VALID wxT("Valid")
306 #define KEY_PROVIDERID wxT("ProviderID")
307 #define KEY_EFFECTTYPE wxT("EffectType")
308 #define KEY_EFFECTFAMILY wxT("EffectFamily")
309 #define KEY_EFFECTDEFAULT wxT("EffectDefault")
310 #define KEY_EFFECTINTERACTIVE wxT("EffectInteractive")
311 #define KEY_EFFECTREALTIME wxT("EffectRealtime")
312 #define KEY_EFFECTAUTOMATABLE wxT("EffectAutomatable")
313 #define KEY_EFFECTTYPE_NONE wxT("None")
314 #define KEY_EFFECTTYPE_ANALYZE wxT("Analyze")
315 #define KEY_EFFECTTYPE_GENERATE wxT("Generate")
316 #define KEY_EFFECTTYPE_PROCESS wxT("Process")
317 #define KEY_EFFECTTYPE_TOOL wxT("Tool")
318 #define KEY_EFFECTTYPE_HIDDEN wxT("Hidden")
319 #define KEY_IMPORTERIDENT wxT("ImporterIdent")
320 //#define KEY_IMPORTERFILTER wxT("ImporterFilter")
321 #define KEY_IMPORTEREXTENSIONS wxT("ImporterExtensions")
322 
323 // ============================================================================
324 //
325 // PluginManagerInterface implementation
326 //
327 // ============================================================================
328 
330  ModuleInterface *provider, ComponentInterface *pInterface )
331 {
332  EffectDefinitionInterface * pEInterface = dynamic_cast<EffectDefinitionInterface*>(pInterface);
333  if( pEInterface )
334  return PluginManager::Get().RegisterPlugin(provider, pEInterface, PluginTypeEffect);
335  ComponentInterface * pCInterface = dynamic_cast<ComponentInterface*>(pInterface);
336  if( pCInterface )
337  return PluginManager::Get().RegisterPlugin(provider, pCInterface);
338  static wxString empty;
339  return empty;
340 }
341 
343  ModuleInterface *provider, ComponentInterface *pInterface )
344 {
345  ComponentInterface * pCInterface = dynamic_cast<ComponentInterface*>(pInterface);
346  if( pCInterface )
347  return PluginManager::Get().RegisterPlugin(provider, pCInterface);
348  static wxString empty;
349  return empty;
350 }
351 
353 {
354  auto pPlugin = GetPlugin( ID );
355  if ( pPlugin )
356  return GetPluginEnabledSetting( *pPlugin );
357  return {};
358 }
359 
361  const PluginDescriptor &desc ) const
362 {
363  switch ( desc.GetPluginType() ) {
364  case PluginTypeModule: {
365  // Retrieve optional family symbol that was recorded in
366  // RegisterPlugin() for the module
367  auto family = desc.GetEffectFamily();
368  if ( family.empty() ) // as for built-in effect and command modules
369  return {};
370  else
371  return wxT('/') + family + wxT("/Enable");
372  }
373  case PluginTypeEffect:
374  // do NOT use GetEffectFamily() for this descriptor, but instead,
375  // delegate to the plugin descriptor of the provider, which may
376  // be different (may be empty)
377  return GetPluginEnabledSetting( desc.GetProviderID() );
378  default:
379  return {};
380  }
381 }
382 
384  const PluginPath &path, const TranslatableString *pName)
385 {
386  for (auto &pair : mPlugins) {
387  if (auto &descriptor = pair.second; descriptor.GetPath() == path) {
388  if (pName)
389  descriptor.SetSymbol(
390  { descriptor.GetSymbol().Internal(), *pName });
391  return true;
392  }
393  }
394  return false;
395 }
396 
398 {
399  PluginDescriptor & plug = CreatePlugin(GetID(module), module, PluginTypeModule);
401 
402  plug.SetEnabled(true);
403  plug.SetValid(true);
404 
405  return plug.GetID();
406 }
407 
409 {
411 
412  plug.SetProviderID(PluginManager::GetID(provider));
413 
414  plug.SetEnabled(true);
415  plug.SetValid(true);
416 
417  return plug.GetID();
418 }
419 
421 {
422  PluginDescriptor & plug = CreatePlugin(GetID(effect), effect, (PluginType)type);
423 
424  plug.SetProviderID(PluginManager::GetID(provider));
425 
426  plug.SetEffectType(effect->GetClassification());
427  plug.SetEffectFamily(effect->GetFamily().Internal());
428  plug.SetEffectInteractive(effect->IsInteractive());
429  plug.SetEffectDefault(effect->IsDefault());
430  plug.SetEffectRealtime(effect->SupportsRealtime());
432 
433  plug.SetEnabled(true);
434  plug.SetValid(true);
435 
436  return plug.GetID();
437 }
438 
439 void PluginManager::FindFilesInPathList(const wxString & pattern,
440  const FilePaths & pathList,
441  FilePaths & files,
442  bool directories)
443 {
444 
445  wxLogNull nolog;
446 
447  // Why bother...
448  if (pattern.empty())
449  {
450  return;
451  }
452 
453  // TODO: We REALLY need to figure out the "Audacity" plug-in path(s)
454 
455  FilePaths paths;
456 
457  // Add the "per-user" plug-ins directory
458  {
459  const wxFileName &ff = FileNames::PlugInDir();
460  paths.push_back(ff.GetFullPath());
461  }
462 
463  // Add the "Audacity" plug-ins directory
465 #if defined(__WXMAC__)
466  // Path ends for example in "Audacity.app/Contents/MacOSX"
467  //ff.RemoveLastDir();
468  //ff.RemoveLastDir();
469  // just remove the MacOSX part.
470  ff.RemoveLastDir();
471 #endif
472  ff.AppendDir(wxT("plug-ins"));
473  paths.push_back(ff.GetPath());
474 
475  // Weed out duplicates
476  for (const auto &filePath : pathList)
477  {
478  ff = filePath;
479  const wxString path{ ff.GetFullPath() };
480  if (paths.Index(path, wxFileName::IsCaseSensitive()) == wxNOT_FOUND)
481  {
482  paths.push_back(path);
483  }
484  }
485 
486  // Find all matching files in each path
487  for (size_t i = 0, cnt = paths.size(); i < cnt; i++)
488  {
489  ff = paths[i] + wxFILE_SEP_PATH + pattern;
490  wxDir::GetAllFiles(ff.GetPath(), &files, ff.GetFullName(), directories ? wxDIR_DEFAULT : wxDIR_FILES);
491  }
492 
493  return;
494 }
495 
497 {
498  return HasGroup(SharedGroup(ID, group));
499 }
500 
502 {
503  return GetSubgroups(SharedGroup(ID, group), subgroups);
504 }
505 
506 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval)
507 {
508  return GetConfig(SharedKey(ID, group, key), value, defval);
509 }
510 
511 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, int & value, int defval)
512 {
513  return GetConfig(SharedKey(ID, group, key), value, defval);
514 }
515 
516 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, bool & value, bool defval)
517 {
518  return GetConfig(SharedKey(ID, group, key), value, defval);
519 }
520 
521 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, float & value, float defval)
522 {
523  return GetConfig(SharedKey(ID, group, key), value, defval);
524 }
525 
526 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, double & value, double defval)
527 {
528  return GetConfig(SharedKey(ID, group, key), value, defval);
529 }
530 
531 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const wxString & value)
532 {
533  return SetConfig(SharedKey(ID, group, key), value);
534 }
535 
536 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const int & value)
537 {
538  return SetConfig(SharedKey(ID, group, key), value);
539 }
540 
541 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const bool & value)
542 {
543  return SetConfig(SharedKey(ID, group, key), value);
544 }
545 
546 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const float & value)
547 {
548  return SetConfig(SharedKey(ID, group, key), value);
549 }
550 
551 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const double & value)
552 {
553  return SetConfig(SharedKey(ID, group, key), value);
554 }
555 
557 {
558  bool result = GetSettings()->DeleteGroup(SharedGroup(ID, group));
559  if (result)
560  {
561  GetSettings()->Flush();
562  }
563 
564  return result;
565 }
566 
568 {
569  bool result = GetSettings()->DeleteEntry(SharedKey(ID, group, key));
570  if (result)
571  {
572  GetSettings()->Flush();
573  }
574 
575  return result;
576 }
577 
579 {
580  return HasGroup(PrivateGroup(ID, group));
581 }
582 
584 {
585  return GetSubgroups(PrivateGroup(ID, group), subgroups);
586 }
587 
588 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval)
589 {
590  return GetConfig(PrivateKey(ID, group, key), value, defval);
591 }
592 
593 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, int & value, int defval)
594 {
595  return GetConfig(PrivateKey(ID, group, key), value, defval);
596 }
597 
598 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, bool & value, bool defval)
599 {
600  return GetConfig(PrivateKey(ID, group, key), value, defval);
601 }
602 
603 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, float & value, float defval)
604 {
605  return GetConfig(PrivateKey(ID, group, key), value, defval);
606 }
607 
608 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, double & value, double defval)
609 {
610  return GetConfig(PrivateKey(ID, group, key), value, defval);
611 }
612 
613 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const wxString & value)
614 {
615  return SetConfig(PrivateKey(ID, group, key), value);
616 }
617 
618 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const int & value)
619 {
620  return SetConfig(PrivateKey(ID, group, key), value);
621 }
622 
623 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const bool & value)
624 {
625  return SetConfig(PrivateKey(ID, group, key), value);
626 }
627 
628 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const float & value)
629 {
630  return SetConfig(PrivateKey(ID, group, key), value);
631 }
632 
633 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const double & value)
634 {
635  return SetConfig(PrivateKey(ID, group, key), value);
636 }
637 
639 {
640  bool result = GetSettings()->DeleteGroup(PrivateGroup(ID, group));
641  if (result)
642  {
643  GetSettings()->Flush();
644  }
645 
646  return result;
647 }
648 
650 {
651  bool result = GetSettings()->DeleteEntry(PrivateKey(ID, group, key));
652  if (result)
653  {
654  GetSettings()->Flush();
655  }
656 
657  return result;
658 }
659 
660 // ============================================================================
661 //
662 // PluginManager
663 //
664 // ============================================================================
665 
666 // The one and only PluginManager
667 std::unique_ptr<PluginManager> PluginManager::mInstance{};
668 
669 // ----------------------------------------------------------------------------
670 // Creation/Destruction
671 // ----------------------------------------------------------------------------
672 
674 {
675  mSettings = NULL;
676 }
677 
679 {
680  // Ensure termination (harmless if already done)
681  Terminate();
682 }
683 
684 // ----------------------------------------------------------------------------
685 // PluginManager implementation
686 // ----------------------------------------------------------------------------
687 
688 // ============================================================================
689 //
690 // Return reference to singleton
691 //
692 // (Thread-safe...no active threading during construction or after destruction)
693 // ============================================================================
694 
696 {
697  if (!mInstance)
698  {
700  }
701 
702  return *mInstance;
703 }
704 
706 {
707  // Always load the registry first
708  Load();
709 
710  // And force load of setting to verify it's accessible
711  GetSettings();
712 
713  auto &mm = ModuleManager::Get();
714  mm.DiscoverProviders();
715  for (const auto &[id, module] : mm.Providers()) {
716  RegisterPlugin(module.get());
717  // Allow the module to auto-register children
718  module->AutoRegisterPlugins(*this);
719  }
720 
721  // And finally check for updates
722 #ifndef EXPERIMENTAL_EFFECT_MANAGEMENT
723  CheckForUpdates();
724 #else
725  const bool kFast = true;
726  CheckForUpdates( kFast );
727 #endif
728 }
729 
731 {
732  // Get rid of all non-module plugins first
733  PluginMap::iterator iter = mPlugins.begin();
734  while (iter != mPlugins.end())
735  {
736  PluginDescriptor & plug = iter->second;
737  if (plug.GetPluginType() == PluginTypeEffect)
738  {
739  mPlugins.erase(iter++);
740  continue;
741  }
742 
743  ++iter;
744  }
745 
746  // Now get rid of the modules
747  iter = mPlugins.begin();
748  while (iter != mPlugins.end())
749  {
750  mPlugins.erase(iter++);
751  }
752 }
753 
754 bool PluginManager::DropFile(const wxString &fileName)
755 {
756  auto &mm = ModuleManager::Get();
757  const wxFileName src{ fileName };
758 
759  for (auto &plug : PluginsOfType(PluginTypeModule)) {
760  auto module = static_cast<ModuleInterface *>
761  (mm.CreateProviderInstance(plug.GetID(), plug.GetPath()));
762  if (! module)
763  continue;
764 
765  const auto &ff = module->InstallPath();
766  const auto &extensions = module->GetFileExtensions();
767  if ( !ff.empty() &&
768  extensions.Index(src.GetExt(), false) != wxNOT_FOUND ) {
769  TranslatableString errMsg;
770  // Do dry-run test of the file format
771  unsigned nPlugIns =
772  module->DiscoverPluginsAtPath(fileName, errMsg, {});
773  if (nPlugIns) {
774  // File contents are good for this module, so check no others.
775  // All branches of this block return true, even in case of
776  // failure for other reasons, to signal that other drag-and-drop
777  // actions should not be tried.
778 
779  // Find path to copy it
780  wxFileName dst;
781  dst.AssignDir( ff );
782  dst.SetFullName( src.GetFullName() );
783  if ( dst.Exists() ) {
784  // Query whether to overwrite
785  bool overwrite = (wxYES == ::AudacityMessageBox(
786  XO("Overwrite the plug-in file %s?")
787  .Format( dst.GetFullPath() ),
788  XO("Plug-in already exists"),
789  wxYES_NO ) );
790  if ( !overwrite )
791  return true;
792  }
793 
794  // Move the file or subtree
795  bool copied = false;
796  auto dstPath = dst.GetFullPath();
797  if ( src.FileExists() )
798  // A simple one-file plug-in
799  copied = FileNames::DoCopyFile(
800  src.GetFullPath(), dstPath, true );
801  else {
802  // A sub-folder
803  // such as for some VST packages
804  // Recursive copy needed -- to do
805  return true;
806  }
807 
808  if (!copied) {
810  XO("Plug-in file is in use. Failed to overwrite") );
811  return true;
812  }
813 
814  // Register for real
815  std::vector<PluginID> ids;
816  std::vector<wxString> names;
817  nPlugIns = module->DiscoverPluginsAtPath(dstPath, errMsg,
818  [&](ModuleInterface *provider, ComponentInterface *ident)
819  -> const PluginID& {
820  // Register as by default, but also collecting the PluginIDs
821  // and names
823  provider, ident);
824  ids.push_back(id);
825  names.push_back( ident->GetSymbol().Translation() );
826  return id;
827  });
828  if ( ! nPlugIns ) {
829  // Unlikely after the dry run succeeded
831  XO("Failed to register:\n%s").Format( errMsg ) );
832  return true;
833  }
834 
835  // Ask whether to enable the plug-ins
836  if (auto nIds = ids.size()) {
837  auto message = XPC(
838  /* i18n-hint A plug-in is an optional added program for a sound
839  effect, or generator, or analyzer */
840  "Enable this plug-in?\n",
841  "Enable these plug-ins?\n",
842  0,
843  "plug-ins"
844  )( nIds );
845  for (const auto &name : names)
846  message.Join( Verbatim( name ), wxT("\n") );
847  bool enable = (wxYES == ::AudacityMessageBox(
848  message,
849  XO("Enable new plug-ins"),
850  wxYES_NO ) );
851  for (const auto &id : ids)
852  mPlugins[id].SetEnabled(enable);
853  // Make changes to enabled status persist:
854  this->Save();
855  }
856 
857  return true;
858  }
859  }
860  }
861 
862  return false;
863 }
864 
866 {
867  // Create/Open the registry
868  auto pRegistry = AudacityFileConfig::Create(
869  {}, {}, FileNames::PluginRegistry());
870  auto &registry = *pRegistry;
871 
872  // If this group doesn't exist then we have something that's not a registry.
873  // We should probably warn the user, but it's pretty unlikely that this will happen.
874  if (!registry.HasGroup(REGROOT))
875  {
876  // Must start over
877  // This DeleteAll affects pluginregistry.cfg only, not audacity.cfg
878  // That is, the memory of on/off states of effect (and generator,
879  // analyzer, and tool) plug-ins
880  registry.DeleteAll();
881  registry.Flush();
882  return;
883  }
884 
885  // Check for a registry version that we can understand
886  // TODO: Should also check for a registry file that is newer than
887  // what we can understand.
888  wxString regver = registry.Read(REGVERKEY);
889  if (regver < REGVERCUR )
890  {
891  // Conversion code here, for when registry version changes.
892 
893  // We iterate through the effects, possibly updating their info.
894  wxString groupName;
895  long groupIndex;
896  wxString group = GetPluginTypeString(PluginTypeEffect);
897  wxString cfgPath = REGROOT + group + wxCONFIG_PATH_SEPARATOR;
898  wxArrayString groupsToDelete;
899 
900  registry.SetPath(cfgPath);
901  for (bool cont = registry.GetFirstGroup(groupName, groupIndex);
902  cont;
903  registry.SetPath(cfgPath),
904  cont = registry.GetNextGroup(groupName, groupIndex))
905  {
906  registry.SetPath(groupName);
907  wxString effectSymbol = registry.Read(KEY_SYMBOL, "");
908  wxString effectVersion = registry.Read(KEY_VERSION, "");
909 
910 
911  // For 2.3.0 the plugins we distribute have moved around.
912  // So we upped the registry version number to 1.1.
913  // These particular config edits were originally written to fix Bug 1914.
914  if (regver <= "1.0") {
915  // Nyquist prompt is a built-in that has moved to the tools menu.
916  if (effectSymbol == NYQUIST_PROMPT_ID) {
917  registry.Write(KEY_EFFECTTYPE, "Tool");
918  // Old version of SDE was in Analyze menu. Now it is in Tools.
919  // We don't want both the old and the new.
920  } else if ((effectSymbol == "Sample Data Export") && (effectVersion == "n/a")) {
921  groupsToDelete.push_back(cfgPath + groupName);
922  // Old version of SDI was in Generate menu. Now it is in Tools.
923  } else if ((effectSymbol == "Sample Data Import") && (effectVersion == "n/a")) {
924  groupsToDelete.push_back(cfgPath + groupName);
925  }
926  }
927 
928  }
929  // Doing the deletion within the search loop risked skipping some items,
930  // hence the delayed delete.
931  for (unsigned int i = 0; i < groupsToDelete.size(); i++) {
932  registry.DeleteGroup(groupsToDelete[i]);
933  }
934  registry.SetPath("");
935  registry.Write(REGVERKEY, REGVERCUR);
936  // Updates done. Make sure we read the updated data later.
937  registry.Flush();
938  }
939 
940  // Load all provider plugins first
941  LoadGroup(&registry, PluginTypeModule);
942 
943  // Now the rest
944  LoadGroup(&registry, PluginTypeEffect);
946  LoadGroup(&registry, PluginTypeExporter);
947  LoadGroup(&registry, PluginTypeImporter);
948 
949  LoadGroup(&registry, PluginTypeStub);
950  return;
951 }
952 
954 {
955 #ifdef __WXMAC__
956  // Bug 1590: On Mac, we should purge the registry of Nyquist plug-ins
957  // bundled with other versions of Audacity, assuming both versions
958  // were properly installed in /Applications (or whatever it is called in
959  // your locale)
960 
961  const auto fullExePath = PlatformCompatibility::GetExecutablePath();
962 
963  // Strip rightmost path components up to *.app
964  wxFileName exeFn{ fullExePath };
965  exeFn.SetEmptyExt();
966  exeFn.SetName(wxString{});
967  while(exeFn.GetDirCount() && !exeFn.GetDirs().back().EndsWith(".app"))
968  exeFn.RemoveLastDir();
969 
970  const auto goodPath = exeFn.GetPath();
971 
972  if(exeFn.GetDirCount())
973  exeFn.RemoveLastDir();
974  const auto possiblyBadPath = exeFn.GetPath();
975 
976  auto AcceptPath = [&](const wxString &path) {
977  if (!path.StartsWith(possiblyBadPath))
978  // Assume it's not under /Applications
979  return true;
980  if (path.StartsWith(goodPath))
981  // It's bundled with this executable
982  return true;
983  return false;
984  };
985 #else
986  auto AcceptPath = [](const wxString&){ return true; };
987 #endif
988 
989  wxString strVal;
990  bool boolVal;
991  wxString groupName;
992  long groupIndex;
993  wxString group = GetPluginTypeString(type);
994  wxString cfgPath = REGROOT + group + wxCONFIG_PATH_SEPARATOR;
995 
996  pRegistry->SetPath(cfgPath);
997  for (bool cont = pRegistry->GetFirstGroup(groupName, groupIndex);
998  cont;
999  pRegistry->SetPath(cfgPath),
1000  cont = pRegistry->GetNextGroup(groupName, groupIndex))
1001  {
1002  PluginDescriptor plug;
1003 
1004  pRegistry->SetPath(groupName);
1005 
1006  groupName = ConvertID(groupName);
1007 
1008  // Bypass group if the ID is already in use
1009  if (mPlugins.count(groupName))
1010  continue;
1011 
1012  // Set the ID and type
1013  plug.SetID(groupName);
1014  plug.SetPluginType(type);
1015 
1016  // Get the provider ID and bypass group if not found
1017  if (!pRegistry->Read(KEY_PROVIDERID, &strVal, wxEmptyString))
1018  {
1019  // Bypass group if the provider isn't valid
1020  if (!strVal.empty() && !mPlugins.count(strVal))
1021  continue;
1022  }
1023  plug.SetProviderID(PluginID(strVal));
1024 
1025  // Get the path (optional)
1026  pRegistry->Read(KEY_PATH, &strVal, wxEmptyString);
1027  if (!AcceptPath(strVal))
1028  // Ignore the obsolete path in the config file, during session,
1029  // but don't remove it from the file. Maybe you really want to
1030  // switch back to the other version of Audacity and lose nothing.
1031  continue;
1032  plug.SetPath(strVal);
1033 
1034  /*
1035  // PRL: Ignore names written in configs before 2.3.0!
1036  // use Internal string only! Let the present version of Audacity map
1037  // that to a user-visible string.
1038  // Get the name and bypass group if not found
1039  if (!pRegistry->Read(KEY_NAME, &strVal))
1040  {
1041  continue;
1042  }
1043  plug.SetName(strVal);
1044  */
1045 
1046  // Get the symbol...Audacity 2.3.0 or later requires it
1047  // bypass group if not found
1048  // Note, KEY_SYMBOL started getting written to config files in 2.1.0.
1049  // KEY_NAME (now ignored) was written before that, but only for VST
1050  // effects.
1051  if (!pRegistry->Read(KEY_SYMBOL, &strVal))
1052  continue;
1053 
1054  // Related to Bug2778: config file only remembered an internal name,
1055  // so this symbol may not contain the correct TranslatableString.
1056  // See calls to IsPluginRegistered which can correct that.
1057  plug.SetSymbol(strVal);
1058 
1059  // Get the version and bypass group if not found
1060  if (!pRegistry->Read(KEY_VERSION, &strVal))
1061  {
1062  continue;
1063  }
1064  plug.SetVersion(strVal);
1065 
1066  // Get the vendor and bypass group if not found
1067  if (!pRegistry->Read(KEY_VENDOR, &strVal))
1068  {
1069  continue;
1070  }
1071  plug.SetVendor( strVal );
1072 
1073 #if 0
1074  // This was done before version 2.2.2, but the value was not really used
1075  // But absence of a value will cause early versions to skip the group
1076  // Therefore we still write a blank to keep pluginregistry.cfg
1077  // backwards-compatible
1078 
1079  // Get the description and bypass group if not found
1080  if (!pRegistry->Read(KEY_DESCRIPTION, &strVal))
1081  {
1082  continue;
1083  }
1084 #endif
1085 
1086  // Is it enabled...default to no if not found
1087  pRegistry->Read(KEY_ENABLED, &boolVal, false);
1088  plug.SetEnabled(boolVal);
1089 
1090  // Is it valid...default to no if not found
1091  pRegistry->Read(KEY_VALID, &boolVal, false);
1092  plug.SetValid(boolVal);
1093 
1094  switch (type)
1095  {
1096  case PluginTypeModule:
1097  {
1098  // Nothing to do here yet
1099  }
1100  break;
1101 
1102  case PluginTypeEffect:
1103  {
1104  // Get the effect type and bypass group if not found
1105  if (!pRegistry->Read(KEY_EFFECTTYPE, &strVal))
1106  continue;
1107 
1108  if (strVal == KEY_EFFECTTYPE_NONE)
1110  else if (strVal == KEY_EFFECTTYPE_ANALYZE)
1112  else if (strVal == KEY_EFFECTTYPE_GENERATE)
1114  else if (strVal == KEY_EFFECTTYPE_PROCESS)
1116  else if (strVal == KEY_EFFECTTYPE_TOOL)
1118  else if (strVal == KEY_EFFECTTYPE_HIDDEN)
1120  else
1121  continue;
1122 
1123  // Get the effect family and bypass group if not found
1124  if (!pRegistry->Read(KEY_EFFECTFAMILY, &strVal))
1125  {
1126  continue;
1127  }
1128  plug.SetEffectFamily(strVal);
1129 
1130  // Is it a default (above the line) effect and bypass group if not found
1131  if (!pRegistry->Read(KEY_EFFECTDEFAULT, &boolVal))
1132  {
1133  continue;
1134  }
1135  plug.SetEffectDefault(boolVal);
1136 
1137  // Is it an interactive effect and bypass group if not found
1138  if (!pRegistry->Read(KEY_EFFECTINTERACTIVE, &boolVal))
1139  {
1140  continue;
1141  }
1142  plug.SetEffectInteractive(boolVal);
1143 
1144  // Is it a realtime capable effect and bypass group if not found
1145  if (!pRegistry->Read(KEY_EFFECTREALTIME, &boolVal))
1146  {
1147  continue;
1148  }
1149  plug.SetEffectRealtime(boolVal);
1150 
1151  // Does the effect support automation...bypass group if not found
1152  if (!pRegistry->Read(KEY_EFFECTAUTOMATABLE, &boolVal))
1153  {
1154  continue;
1155  }
1156  plug.SetEffectAutomatable(boolVal);
1157  }
1158  break;
1159 
1160  case PluginTypeImporter:
1161  {
1162  // Get the importer identifier and bypass group if not found
1163  if (!pRegistry->Read(KEY_IMPORTERIDENT, &strVal))
1164  {
1165  continue;
1166  }
1167  plug.SetImporterIdentifier(strVal);
1168 
1169  // Get the importer extensions and bypass group if not found
1170  if (!pRegistry->Read(KEY_IMPORTEREXTENSIONS, &strVal))
1171  {
1172  continue;
1173  }
1174  FileExtensions extensions;
1175  wxStringTokenizer tkr(strVal, wxT(":"));
1176  while (tkr.HasMoreTokens())
1177  {
1178  extensions.push_back(tkr.GetNextToken());
1179  }
1180  plug.SetImporterExtensions(extensions);
1181  }
1182  break;
1183 
1184  case PluginTypeStub:
1185  {
1186  // Nothing additional for stubs
1187  }
1188  break;
1189 
1190  // Not used by 2.1.1 or greater and should be removed after a few releases past 2.1.0.
1191  case PluginTypeNone:
1192  {
1193  // Used for stub groups
1194  }
1195  break;
1196 
1197  default:
1198  {
1199  continue;
1200  }
1201  }
1202 
1203  // Everything checked out...accept the plugin
1204  mPlugins[groupName] = std::move(plug);
1205  }
1206 
1207  return;
1208 }
1209 
1211 {
1212  // Create/Open the registry
1213  auto pRegistry = AudacityFileConfig::Create(
1214  {}, {}, FileNames::PluginRegistry());
1215  auto &registry = *pRegistry;
1216 
1217  // Clear pluginregistry.cfg (not audacity.cfg)
1218  registry.DeleteAll();
1219 
1220  // Write the version string
1221  registry.Write(REGVERKEY, REGVERCUR);
1222 
1223  // Save the individual groups
1224  SaveGroup(&registry, PluginTypeEffect);
1225  SaveGroup(&registry, PluginTypeExporter);
1227  SaveGroup(&registry, PluginTypeImporter);
1228  SaveGroup(&registry, PluginTypeStub);
1229 
1230  // Not used by 2.1.1 or greater, but must save to allow users to switch between 2.1.0
1231  // and 2.1.1+. This should be removed after a few releases past 2.1.0.
1232  //SaveGroup(&registry, PluginTypeNone);
1233 
1234  // And now the providers
1235  SaveGroup(&registry, PluginTypeModule);
1236 
1237  // Just to be safe
1238  registry.Flush();
1239 }
1240 
1242 {
1243  wxString group = GetPluginTypeString(type);
1244  for (auto &pair : mPlugins) {
1245  auto & plug = pair.second;
1246 
1247  if (plug.GetPluginType() != type)
1248  {
1249  continue;
1250  }
1251 
1252  pRegistry->SetPath(REGROOT + group + wxCONFIG_PATH_SEPARATOR + ConvertID(plug.GetID()));
1253 
1254  pRegistry->Write(KEY_PATH, plug.GetPath());
1255 
1256  // See comments with the corresponding load-time call to SetSymbol().
1257  pRegistry->Write(KEY_SYMBOL, plug.GetSymbol().Internal());
1258 
1259  // PRL: Writing KEY_NAME which is no longer read, but older Audacity
1260  // versions expect to find it.
1261  pRegistry->Write(KEY_NAME, plug.GetSymbol().Msgid().MSGID());
1262 
1263  pRegistry->Write(KEY_VERSION, plug.GetUntranslatedVersion());
1264  pRegistry->Write(KEY_VENDOR, plug.GetVendor());
1265  // Write a blank -- see comments in LoadGroup:
1266  pRegistry->Write(KEY_DESCRIPTION, wxString{});
1267  pRegistry->Write(KEY_PROVIDERID, plug.GetProviderID());
1268  pRegistry->Write(KEY_ENABLED, plug.IsEnabled());
1269  pRegistry->Write(KEY_VALID, plug.IsValid());
1270 
1271  switch (type)
1272  {
1273  case PluginTypeModule:
1274  break;
1275 
1276  case PluginTypeEffect:
1277  {
1278  EffectType etype = plug.GetEffectType();
1279  wxString stype;
1280  if (etype == EffectTypeNone)
1281  stype = KEY_EFFECTTYPE_NONE;
1282  else if (etype == EffectTypeAnalyze)
1283  stype = KEY_EFFECTTYPE_ANALYZE;
1284  else if (etype == EffectTypeGenerate)
1285  stype = KEY_EFFECTTYPE_GENERATE;
1286  else if (etype == EffectTypeProcess)
1287  stype = KEY_EFFECTTYPE_PROCESS;
1288  else if (etype == EffectTypeTool)
1289  stype = KEY_EFFECTTYPE_TOOL;
1290  else if (etype == EffectTypeHidden)
1291  stype = KEY_EFFECTTYPE_HIDDEN;
1292 
1293  pRegistry->Write(KEY_EFFECTTYPE, stype);
1294  pRegistry->Write(KEY_EFFECTFAMILY, plug.GetEffectFamily());
1295  pRegistry->Write(KEY_EFFECTDEFAULT, plug.IsEffectDefault());
1296  pRegistry->Write(KEY_EFFECTINTERACTIVE, plug.IsEffectInteractive());
1297  pRegistry->Write(KEY_EFFECTREALTIME, plug.IsEffectRealtime());
1298  pRegistry->Write(KEY_EFFECTAUTOMATABLE, plug.IsEffectAutomatable());
1299  }
1300  break;
1301 
1302  case PluginTypeImporter:
1303  {
1304  pRegistry->Write(KEY_IMPORTERIDENT, plug.GetImporterIdentifier());
1305  const auto & extensions = plug.GetImporterExtensions();
1306  wxString strExt;
1307  for (size_t i = 0, cnt = extensions.size(); i < cnt; i++)
1308  {
1309  strExt += extensions[i] + wxT(":");
1310  }
1311  strExt.RemoveLast(1);
1312  pRegistry->Write(KEY_IMPORTEREXTENSIONS, strExt);
1313  }
1314  break;
1315 
1316  default:
1317  break;
1318  }
1319  }
1320 
1321  return;
1322 }
1323 
1324 // If bFast is true, do not do a full check. Just check the ones
1325 // that are quick to check. Currently (Feb 2017) just Nyquist
1326 // and built-ins.
1328 {
1330  wxArrayString pathIndex;
1331  for (auto &pair : mPlugins) {
1332  auto &plug = pair.second;
1333 
1334  // Bypass 2.1.0 placeholders...remove this after a few releases past 2.1.0
1335  if (plug.GetPluginType() != PluginTypeNone)
1336  pathIndex.push_back(plug.GetPath().BeforeFirst(wxT(';')));
1337  }
1338 
1339  // Check all known plugins to ensure they are still valid and scan for NEW ones.
1340  //
1341  // All NEW plugins get a stub entry created that will remain in place until the
1342  // user enables or disables the plugin.
1343  //
1344  // Because we use the plugins "path" as returned by the providers, we can actually
1345  // have multiple providers report the same path since, at this point, they only
1346  // know that the path might possibly be one supported by the provider.
1347  //
1348  // When the user enables the plugin, each provider that reported it will be asked
1349  // to register the plugin.
1350  for (auto &pair : mPlugins) {
1351  auto &plug = pair.second;
1352  const PluginID & plugID = plug.GetID();
1353  const wxString & plugPath = plug.GetPath();
1354  PluginType plugType = plug.GetPluginType();
1355 
1356  // Bypass 2.1.0 placeholders...remove this after a few releases past 2.1.0
1357  if (plugType == PluginTypeNone)
1358  {
1359  continue;
1360  }
1361 
1362  if ( plugType == PluginTypeModule )
1363  {
1364  if( bFast )
1365  {
1366  // Skip modules, when doing a fast refresh/check.
1367  }
1368  else if (!mm.IsProviderValid(plugID, plugPath))
1369  {
1370  plug.SetEnabled(false);
1371  plug.SetValid(false);
1372  }
1373  else
1374  {
1375  // Collect plugin paths
1376  PluginPaths paths;
1377  if (auto provider = mm.CreateProviderInstance( plugID, plugPath ) )
1378  paths = provider->FindPluginPaths( *this );
1379  for (size_t i = 0, cnt = paths.size(); i < cnt; i++)
1380  {
1381  wxString path = paths[i].BeforeFirst(wxT(';'));;
1382  if ( ! make_iterator_range( pathIndex ).contains( path ) )
1383  {
1384  PluginID ID = plugID + wxT("_") + path;
1385  PluginDescriptor & plug2 = mPlugins[ID]; // This will create a NEW descriptor
1387  plug2.SetID(ID);
1388  plug2.SetProviderID(plugID);
1389  plug2.SetPath(path);
1390  plug2.SetEnabled(false);
1391  plug2.SetValid(false);
1392  }
1393  }
1394  }
1395  }
1396  else if (plugType != PluginTypeNone && plugType != PluginTypeStub)
1397  {
1398  plug.SetValid(mm.IsPluginValid(plug.GetProviderID(), plugPath, bFast));
1399  if (!plug.IsValid())
1400  {
1401  plug.SetEnabled(false);
1402  }
1403  }
1404  }
1405 
1406  Save();
1407 
1408  return;
1409 }
1410 
1411 // Here solely for the purpose of Nyquist Workbench until
1412 // a better solution is devised.
1414  std::unique_ptr<EffectDefinitionInterface> effect, PluginType type)
1415 {
1416  PluginDescriptor & plug =
1417  CreatePlugin(GetID(effect.get()), effect.get(), type);
1418 
1419  plug.SetEffectType(effect->GetType());
1420  plug.SetEffectFamily(effect->GetFamily().Internal());
1421  plug.SetEffectInteractive(effect->IsInteractive());
1422  plug.SetEffectDefault(effect->IsDefault());
1423  plug.SetEffectRealtime(effect->SupportsRealtime());
1424  plug.SetEffectAutomatable(effect->SupportsAutomation());
1425 
1426  plug.SetInstance(std::move(effect));
1427  plug.SetEffectLegacy(true);
1428  plug.SetEnabled(true);
1429  plug.SetValid(true);
1430 
1431  return plug.GetID();
1432 }
1433 
1435 {
1436  mPlugins.erase(ID);
1437 }
1438 
1440 {
1441  return count_if(mPlugins.begin(), mPlugins.end(), [type](auto &pair){
1442  return pair.second.GetPluginType() == type; });
1443 }
1444 
1446 {
1447  if (auto iter = mPlugins.find(ID); iter == mPlugins.end())
1448  return nullptr;
1449  else
1450  return &iter->second;
1451 }
1452 
1453 void PluginManager::Iterator::Advance(bool incrementing)
1454 {
1455  const auto end = mPm.mPlugins.end();
1456  if (incrementing && mIterator != end)
1457  ++mIterator;
1459  for (; mIterator != end; ++mIterator) {
1460  auto &plug = mIterator->second;
1461  if (!all && !(plug.IsValid() && plug.IsEnabled()))
1462  continue;
1463  auto plugType = plug.GetPluginType();
1464  if ((mPluginType == PluginTypeNone || (plugType & mPluginType)) &&
1465  (mEffectType == EffectTypeNone || plug.GetEffectType() == mEffectType)) {
1466  if (!all && (plugType & PluginTypeEffect)) {
1467  // This preference may be written by EffectsPrefs
1468  auto setting = mPm.GetPluginEnabledSetting( plug );
1469  if (!(setting.empty() || gPrefs->Read( setting, true )))
1470  continue;
1471  }
1472  // Pause iteration at this match
1473  break;
1474  }
1475  }
1476 }
1477 
1479 : mPm{ manager }
1480 , mIterator{ manager.mPlugins.begin() }
1481 {
1482 }
1483 
1485 : mPm{ manager }
1486 , mIterator{ manager.mPlugins.begin() }
1487 , mPluginType{ type }
1488 {
1489  Advance(false);
1490 }
1491 
1493 : mPm{ manager }
1494 , mIterator{ manager.mPlugins.begin() }
1495 , mEffectType{ type }
1496 {
1497  Advance(false);
1498 }
1499 
1501 {
1502  Advance(true);
1503  return *this;
1504 }
1505 
1507 {
1508  if (auto iter = mPlugins.find(ID); iter == mPlugins.end())
1509  return false;
1510  else
1511  return iter->second.IsEnabled();
1512 }
1513 
1514 void PluginManager::EnablePlugin(const PluginID & ID, bool enable)
1515 {
1516  if (auto iter = mPlugins.find(ID); iter == mPlugins.end())
1517  return;
1518  else
1519  iter->second.SetEnabled(enable);
1520 }
1521 
1523 {
1524  if (auto iter = mPlugins.find(ID); iter == mPlugins.end()) {
1525  static ComponentInterfaceSymbol empty;
1526  return empty;
1527  }
1528  else
1529  return iter->second.GetSymbol();
1530 }
1531 
1533 {
1534  if (auto iter = mPlugins.find(ID); iter == mPlugins.end())
1535  return nullptr;
1536  else {
1537  auto &plug = iter->second;
1538 
1539  // If not dealing with legacy effects, make sure the provider is loaded
1540  if (!plug.IsEffectLegacy())
1541  {
1542  const PluginID & prov = plug.GetProviderID();
1543  if (auto iter2 = mPlugins.find(prov); iter2 == mPlugins.end())
1544  return nullptr;
1545  else
1546  iter2->second.GetInstance();
1547  }
1548 
1549  return plug.GetInstance();
1550  }
1551 }
1552 
1554 {
1555  return ModuleManager::GetID(module);
1556 }
1557 
1559 {
1560  return wxString::Format(wxT("%s_%s_%s_%s_%s"),
1562  wxEmptyString,
1563  command->GetVendor().Internal(),
1564  command->GetSymbol().Internal(),
1565  command->GetPath());
1566 }
1567 
1569 {
1570  return wxString::Format(wxT("%s_%s_%s_%s_%s"),
1572  effect->GetFamily().Internal(),
1573  effect->GetVendor().Internal(),
1574  effect->GetSymbol().Internal(),
1575  effect->GetPath());
1576 }
1577 
1578 // This string persists in configuration files
1579 // So config compatibility will break if it is changed across Audacity versions
1581 {
1582  wxString str;
1583 
1584  switch (type)
1585  {
1586  default:
1587  case PluginTypeNone:
1588  str = wxT("Placeholder");
1589  break;
1590  case PluginTypeStub:
1591  str = wxT("Stub");
1592  break;
1593  case PluginTypeEffect:
1594  str = wxT("Effect");
1595  break;
1597  str = wxT("Generic");
1598  break;
1599  case PluginTypeExporter:
1600  str = wxT("Exporter");
1601  break;
1602  case PluginTypeImporter:
1603  str = wxT("Importer");
1604  break;
1605  case PluginTypeModule:
1607  break;
1608  }
1609 
1610  return str;
1611 }
1612 
1615  PluginType type)
1616 {
1617  // This will either create a NEW entry or replace an existing entry
1618  PluginDescriptor & plug = mPlugins[id];
1619 
1620  plug.SetPluginType(type);
1621 
1622  plug.SetID(id);
1623  plug.SetPath(ident->GetPath());
1624  plug.SetSymbol(ident->GetSymbol());
1625  plug.SetVendor(ident->GetVendor().Internal());
1626  plug.SetVersion(ident->GetVersion());
1627 
1628  return plug;
1629 }
1630 
1632 {
1633  if (!mSettings)
1634  {
1635  mSettings =
1637 
1638  // Check for a settings version that we can understand
1639  if (mSettings->HasEntry(SETVERKEY))
1640  {
1641  wxString setver = mSettings->Read(SETVERKEY, SETVERKEY);
1642  if (setver < SETVERCUR )
1643  {
1644  // This is where we'd put in conversion code when the
1645  // settings version changes.
1646  //
1647  // Should also check for a settings file that is newer than
1648  // what we can understand.
1649  }
1650  }
1651  else
1652  {
1653  // Make sure is has a version string
1654  mSettings->Write(SETVERKEY, SETVERCUR);
1655  mSettings->Flush();
1656  }
1657  }
1658 
1659  return mSettings.get();
1660 }
1661 
1663 {
1664  auto settings = GetSettings();
1665 
1666  bool res = settings->HasGroup(group);
1667  if (res)
1668  {
1669  // The group exists, but empty groups aren't considered valid
1670  wxString oldPath = settings->GetPath();
1671  settings->SetPath(group);
1672  res = settings->GetNumberOfEntries() || settings->GetNumberOfGroups();
1673  settings->SetPath(oldPath);
1674  }
1675 
1676  return res;
1677 }
1678 
1680 {
1681  if (group.empty() || !HasGroup(group))
1682  {
1683  return false;
1684  }
1685 
1686  wxString path = GetSettings()->GetPath();
1687  GetSettings()->SetPath(group);
1688 
1689  wxString name;
1690  long index = 0;
1691  if (GetSettings()->GetFirstGroup(name, index))
1692  {
1693  do
1694  {
1695  subgroups.push_back(name);
1696  } while (GetSettings()->GetNextGroup(name, index));
1697  }
1698 
1699  GetSettings()->SetPath(path);
1700 
1701  return true;
1702 }
1703 
1704 bool PluginManager::GetConfig(const RegistryPath & key, int & value, int defval)
1705 {
1706  bool result = false;
1707 
1708  if (!key.empty())
1709  {
1710  result = GetSettings()->Read(key, &value, defval);
1711  }
1712 
1713  return result;
1714 }
1715 
1716 bool PluginManager::GetConfig(const RegistryPath & key, wxString & value, const wxString & defval)
1717 {
1718  bool result = false;
1719 
1720  if (!key.empty())
1721  {
1722  wxString wxval;
1723 
1724  result = GetSettings()->Read(key, &wxval, defval);
1725 
1726  value = wxval;
1727  }
1728 
1729  return result;
1730 }
1731 
1732 bool PluginManager::GetConfig(const RegistryPath & key, bool & value, bool defval)
1733 {
1734  bool result = false;
1735 
1736  if (!key.empty())
1737  {
1738  result = GetSettings()->Read(key, &value, defval);
1739  }
1740 
1741  return result;
1742 }
1743 
1744 bool PluginManager::GetConfig(const RegistryPath & key, float & value, float defval)
1745 {
1746  bool result = false;
1747 
1748  if (!key.empty())
1749  {
1750  double dval = 0.0;
1751 
1752  result = GetSettings()->Read(key, &dval, (double) defval);
1753 
1754  value = (float) dval;
1755  }
1756 
1757  return result;
1758 }
1759 
1760 bool PluginManager::GetConfig(const RegistryPath & key, double & value, double defval)
1761 {
1762  bool result = false;
1763 
1764  if (!key.empty())
1765  {
1766  result = GetSettings()->Read(key, &value, defval);
1767  }
1768 
1769  return result;
1770 }
1771 
1772 bool PluginManager::SetConfig(const RegistryPath & key, const wxString & value)
1773 {
1774  bool result = false;
1775 
1776  if (!key.empty())
1777  {
1778  wxString wxval = value;
1779  result = GetSettings()->Write(key, wxval);
1780  if (result)
1781  {
1782  result = GetSettings()->Flush();
1783  }
1784  }
1785 
1786  return result;
1787 }
1788 
1789 bool PluginManager::SetConfig(const RegistryPath & key, const int & value)
1790 {
1791  bool result = false;
1792 
1793  if (!key.empty())
1794  {
1795  result = GetSettings()->Write(key, value);
1796  if (result)
1797  {
1798  result = GetSettings()->Flush();
1799  }
1800  }
1801 
1802  return result;
1803 }
1804 
1805 bool PluginManager::SetConfig(const RegistryPath & key, const bool & value)
1806 {
1807  bool result = false;
1808 
1809  if (!key.empty())
1810  {
1811  result = GetSettings()->Write(key, value);
1812  if (result)
1813  {
1814  result = GetSettings()->Flush();
1815  }
1816  }
1817 
1818  return result;
1819 }
1820 
1821 bool PluginManager::SetConfig(const RegistryPath & key, const float & value)
1822 {
1823  bool result = false;
1824 
1825  if (!key.empty())
1826  {
1827  result = GetSettings()->Write(key, value);
1828  if (result)
1829  {
1830  result = GetSettings()->Flush();
1831  }
1832  }
1833 
1834  return result;
1835 }
1836 
1837 bool PluginManager::SetConfig(const RegistryPath & key, const double & value)
1838 {
1839  bool result = false;
1840 
1841  if (!key.empty())
1842  {
1843  result = GetSettings()->Write(key, value);
1844  if (result)
1845  {
1846  result = GetSettings()->Flush();
1847  }
1848  }
1849 
1850  return result;
1851 }
1852 
1853 /* Return value is a key for lookup in a config file */
1855 {
1856  // All the strings reported by PluginDescriptor and used in this function
1857  // persist in the plugin settings configuration file, so they should not
1858  // be changed across Audacity versions, or else compatibility of the
1859  // configuration files will break.
1860 
1861  if (auto iter = mPlugins.find(ID); iter == mPlugins.end())
1862  return {};
1863  else {
1864  const PluginDescriptor & plug = iter->second;
1865 
1866  wxString id = GetPluginTypeString(plug.GetPluginType()) +
1867  wxT("_") +
1868  plug.GetEffectFamily() + // is empty for non-Effects
1869  wxT("_") +
1870  plug.GetVendor() +
1871  wxT("_") +
1872  (shared ? wxString{} : plug.GetSymbol().Internal());
1873 
1874  return SETROOT +
1875  ConvertID(id) +
1876  wxCONFIG_PATH_SEPARATOR +
1877  (shared ? wxT("shared") : wxT("private")) +
1878  wxCONFIG_PATH_SEPARATOR;
1879  }
1880 }
1881 
1882 /* Return value is a key for lookup in a config file */
1884 {
1885  wxString path = SettingsPath(ID, true);
1886 
1887  wxFileName ff(group);
1888  if (!ff.GetName().empty())
1889  {
1890  path += ff.GetFullPath(wxPATH_UNIX) + wxCONFIG_PATH_SEPARATOR;
1891  }
1892 
1893  return path;
1894 }
1895 
1896 /* Return value is a key for lookup in a config file */
1898 {
1899  auto path = SharedGroup(ID, group);
1900  if (path.empty())
1901  {
1902  return path;
1903  }
1904 
1905  return path + key;
1906 }
1907 
1908 /* Return value is a key for lookup in a config file */
1910 {
1911  auto path = SettingsPath(ID, false);
1912 
1913  wxFileName ff(group);
1914  if (!ff.GetName().empty())
1915  {
1916  path += ff.GetFullPath(wxPATH_UNIX) + wxCONFIG_PATH_SEPARATOR;
1917  }
1918 
1919  return path;
1920 }
1921 
1922 /* Return value is a key for lookup in a config file */
1924 {
1925  auto path = PrivateGroup(ID, group);
1926  if (path.empty())
1927  {
1928  return path;
1929  }
1930 
1931  return path + key;
1932 }
1933 
1934 // Sanitize the ID...not the best solution, but will suffice until this
1935 // is converted to XML. We use base64 encoding to preserve case.
1937 {
1938  if (ID.StartsWith(wxT("base64:")))
1939  {
1940  wxString id = ID.Mid(7);
1941  ArrayOf<char> buf{ id.length() / 4 * 3 };
1942  id = wxString::FromUTF8(buf.get(), b64decode(id, buf.get()));
1943  return id;
1944  }
1945 
1946  const wxCharBuffer & buf = ID.ToUTF8();
1947  return wxT("base64:") + b64encode(buf, strlen(buf));
1948 }
1949 
1951 // Base64 en/decoding
1952 //
1953 // Original routines marked as public domain and found at:
1954 //
1955 // http://en.wikibooks.org/wiki/Algorithm_implementation/Miscellaneous/Base64
1956 //
1958 
1959 // Lookup table for encoding
1960 const static wxChar cset[] = wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
1961 const static char padc = wxT('=');
1962 
1963 wxString PluginManager::b64encode(const void *in, int len)
1964 {
1965  unsigned char *p = (unsigned char *) in;
1966  wxString out;
1967 
1968  unsigned long temp;
1969  for (int i = 0; i < len / 3; i++)
1970  {
1971  temp = (*p++) << 16; //Convert to big endian
1972  temp += (*p++) << 8;
1973  temp += (*p++);
1974  out += cset[(temp & 0x00FC0000) >> 18];
1975  out += cset[(temp & 0x0003F000) >> 12];
1976  out += cset[(temp & 0x00000FC0) >> 6];
1977  out += cset[(temp & 0x0000003F)];
1978  }
1979 
1980  switch (len % 3)
1981  {
1982  case 1:
1983  temp = (*p++) << 16; //Convert to big endian
1984  out += cset[(temp & 0x00FC0000) >> 18];
1985  out += cset[(temp & 0x0003F000) >> 12];
1986  out += padc;
1987  out += padc;
1988  break;
1989 
1990  case 2:
1991  temp = (*p++) << 16; //Convert to big endian
1992  temp += (*p++) << 8;
1993  out += cset[(temp & 0x00FC0000) >> 18];
1994  out += cset[(temp & 0x0003F000) >> 12];
1995  out += cset[(temp & 0x00000FC0) >> 6];
1996  out += padc;
1997  break;
1998  }
1999 
2000  return out;
2001 }
2002 
2003 int PluginManager::b64decode(const wxString &in, void *out)
2004 {
2005  int len = in.length();
2006  unsigned char *p = (unsigned char *) out;
2007 
2008  if (len % 4) //Sanity check
2009  {
2010  return 0;
2011  }
2012 
2013  int padding = 0;
2014  if (len)
2015  {
2016  if (in[len - 1] == padc)
2017  {
2018  padding++;
2019  }
2020 
2021  if (in[len - 2] == padc)
2022  {
2023  padding++;
2024  }
2025  }
2026 
2027  //const char *a = in.mb_str();
2028  //Setup a vector to hold the result
2029  unsigned long temp = 0; //Holds decoded quanta
2030  int i = 0;
2031  while (i < len)
2032  {
2033  for (int quantumPosition = 0; quantumPosition < 4; quantumPosition++)
2034  {
2035  unsigned char c = in[i];
2036  temp <<= 6;
2037 
2038  if (c >= 0x41 && c <= 0x5A)
2039  {
2040  temp |= c - 0x41;
2041  }
2042  else if (c >= 0x61 && c <= 0x7A)
2043  {
2044  temp |= c - 0x47;
2045  }
2046  else if (c >= 0x30 && c <= 0x39)
2047  {
2048  temp |= c + 0x04;
2049  }
2050  else if (c == 0x2B)
2051  {
2052  temp |= 0x3E;
2053  }
2054  else if (c == 0x2F)
2055  {
2056  temp |= 0x3F;
2057  }
2058  else if (c == padc)
2059  {
2060  switch (len - i)
2061  {
2062  case 1: //One pad character
2063  *p++ = (temp >> 16) & 0x000000FF;
2064  *p++ = (temp >> 8) & 0x000000FF;
2065  return p - (unsigned char *) out;
2066  case 2: //Two pad characters
2067  *p++ = (temp >> 10) & 0x000000FF;
2068  return p - (unsigned char *) out;
2069  }
2070  }
2071  i++;
2072  }
2073  *p++ = (temp >> 16) & 0x000000FF;
2074  *p++ = (temp >> 8) & 0x000000FF;
2075  *p++ = temp & 0x000000FF;
2076  }
2077 
2078  return p - (unsigned char *) out;
2079 }
2080 
2081 // This is defined out-of-line here, to keep ComponentInterface free of other
2082 // #include directives.
2084 {
2085  return GetSymbol().Msgid();
2086 }
PluginManager::b64decode
int b64decode(const wxString &in, void *out)
Definition: PluginManager.cpp:2003
PluginDescriptor::mEffectLegacy
bool mEffectLegacy
Definition: PluginManager.h:151
FileConfig::SetPath
virtual void SetPath(const wxString &strPath) wxOVERRIDE
Definition: FileConfig.cpp:93
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
PluginManager::GetInstance
ComponentInterface * GetInstance(const PluginID &ID)
Definition: PluginManager.cpp:1532
PluginDescriptor::mVendor
wxString mVendor
Definition: PluginManager.h:140
NYQUIST_PROMPT_ID
#define NYQUIST_PROMPT_ID
Definition: PluginManager.h:360
PluginTypeEffect
@ PluginTypeEffect
Definition: PluginManager.h:35
PluginManager::RemovePrivateConfigSubgroup
bool RemovePrivateConfigSubgroup(const PluginID &ID, const RegistryPath &group) override
Definition: PluginManager.cpp:638
KEY_EFFECTFAMILY
#define KEY_EFFECTFAMILY
Definition: PluginManager.cpp:308
PluginManager::Save
void Save()
Save to preferences.
Definition: PluginManager.cpp:1210
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:59
PluginDescriptor::IsEffectInteractive
bool IsEffectInteractive() const
Definition: PluginManager.cpp:197
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:551
PluginManager::GetSharedConfig
bool GetSharedConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key, wxString &value, const wxString &defval=_T("")) override
Definition: PluginManager.cpp:506
PluginManager::GetPluginTypeString
static wxString GetPluginTypeString(PluginType type)
Definition: PluginManager.cpp:1580
PluginManagerInterface::AudacityCommandRegistrationCallback
static const PluginID & AudacityCommandRegistrationCallback(ModuleInterface *provider, ComponentInterface *ident)
Definition: PluginManager.cpp:342
PluginDescriptor::mInstance
ComponentInterface * mInstance
Definition: PluginManager.h:132
PluginManager::Iterator::Iterator
Iterator(PluginManager &manager)
Iterates all, even disabled.
Definition: PluginManager.cpp:1478
PluginDescriptor::IsEffectRealtime
bool IsEffectRealtime() const
Definition: PluginManager.cpp:212
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Definition: AudacityMessageBox.cpp:17
PluginManager::Iterator::mPluginType
int mPluginType
Definition: PluginManager.h:272
PluginManager::mPlugins
PluginMap mPlugins
Definition: PluginManager.h:354
ComponentInterface::GetSymbol
virtual ComponentInterfaceSymbol GetSymbol()=0
PluginManager::IsPluginRegistered
bool IsPluginRegistered(const PluginPath &path, const TranslatableString *pSymbol) override
Was the plugin registry already populated for a path (maybe from loading the config file)?
Definition: PluginManager.cpp:383
PluginDescriptor::GetEffectFamily
wxString GetEffectFamily() const
Definition: PluginManager.cpp:187
KEY_EFFECTTYPE_NONE
#define KEY_EFFECTTYPE_NONE
Definition: PluginManager.cpp:313
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
PluginDescriptor::SetPath
void SetPath(const PluginPath &path)
Definition: PluginManager.cpp:155
PluginManager::PluginManager
PluginManager()
Definition: PluginManager.cpp:673
PluginManager::SharedKey
RegistryPath SharedKey(const PluginID &ID, const RegistryPath &group, const RegistryPath &key)
Definition: PluginManager.cpp:1897
PluginManager::FindFilesInPathList
void FindFilesInPathList(const wxString &pattern, const FilePaths &pathList, FilePaths &files, bool directories=false) override
Definition: PluginManager.cpp:439
PluginDescriptor::GetImporterExtensions
const FileExtensions & GetImporterExtensions() const
Definition: PluginManager.cpp:269
PluginDescriptor::operator=
PluginDescriptor & operator=(PluginDescriptor &&)
PluginDescriptor::SetEffectAutomatable
void SetEffectAutomatable(bool automatable)
Definition: PluginManager.cpp:252
ident
static CommandHandlerObject & ident(AudacityProject &project)
Definition: ModNullCallback.cpp:65
PluginManager::GetConfig
bool GetConfig(const RegistryPath &key, wxString &value, const wxString &defval=L"")
Definition: PluginManager.cpp:1716
ModuleManager.h
PluginDescriptor::GetProviderID
const wxString & GetProviderID() const
Definition: PluginManager.cpp:105
EffectTypeGenerate
@ EffectTypeGenerate
Definition: EffectInterface.h:58
PluginManager::GetSymbol
const ComponentInterfaceSymbol & GetSymbol(const PluginID &ID)
Definition: PluginManager.cpp:1522
cset
static const wxChar cset[]
Definition: PluginManager.cpp:1960
PluginDescriptor::GetPluginType
PluginType GetPluginType() const
Definition: PluginManager.cpp:95
ModuleManager::GetID
static PluginID GetID(ModuleInterface *module)
Definition: ModuleManager.cpp:410
RegistryPaths
std::vector< RegistryPath > RegistryPaths
Definition: Identifier.h:219
PluginPath
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
KEY_IMPORTEREXTENSIONS
#define KEY_IMPORTEREXTENSIONS
Definition: PluginManager.cpp:321
Format
Abstract base class used in importing a file.
KEY_PATH
#define KEY_PATH
Definition: PluginManager.cpp:297
PluginDescriptor::mVersion
wxString mVersion
Definition: PluginManager.h:139
ModuleInterface.h
EffectTypeNone
@ EffectTypeNone
Definition: EffectInterface.h:56
SETVERKEY
#define SETVERKEY
Definition: PluginManager.cpp:292
EffectDefinitionInterface::IsInteractive
virtual bool IsInteractive()=0
PluginManager::RegisterPlugin
const PluginID & RegisterPlugin(ModuleInterface *module) override
Definition: PluginManager.cpp:397
PluginDescriptor::mProviderID
wxString mProviderID
Definition: PluginManager.h:141
FileConfig::DeleteEntry
virtual bool DeleteEntry(const wxString &key, bool bDeleteGroupIfEmpty=true) wxOVERRIDE
Definition: FileConfig.cpp:209
XO
#define XO(s)
Definition: Internat.h:31
PluginDescriptor::SetEffectInteractive
void SetEffectInteractive(bool interactive)
Definition: PluginManager.cpp:232
FileNames::PlugInDir
FILES_API FilePath PlugInDir()
The user plug-in directory (not a system one)
PluginManager::GetSharedConfigSubgroups
bool GetSharedConfigSubgroups(const PluginID &ID, const RegistryPath &group, RegistryPaths &subgroups) override
Definition: PluginManager.cpp:501
PluginManager::RemoveSharedConfig
bool RemoveSharedConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key) override
Definition: PluginManager.cpp:567
ModuleManager::CreateInstance
std::unique_ptr< ComponentInterface > CreateInstance(const PluginID &provider, const PluginPath &path)
Definition: ModuleManager.cpp:514
FileNames::PluginSettings
FILES_API FilePath PluginSettings()
PluginDescriptor::IsEffectAutomatable
bool IsEffectAutomatable() const
Definition: PluginManager.cpp:217
ModuleInterface::InstallPath
virtual FilePath InstallPath()=0
KEY_IMPORTERIDENT
#define KEY_IMPORTERIDENT
Definition: PluginManager.cpp:319
EffectDefinitionInterface::SupportsRealtime
virtual bool SupportsRealtime()=0
ModuleManager::IsPluginValid
bool IsPluginValid(const PluginID &provider, const PluginPath &path, bool bFast)
Definition: ModuleManager.cpp:542
FileConfig::GetFirstGroup
virtual bool GetFirstGroup(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:103
EffectDefinitionInterface::SupportsAutomation
virtual bool SupportsAutomation()=0
PluginDescriptor::muInstance
std::unique_ptr< ComponentInterface > muInstance
Definition: PluginManager.h:131
PluginManager::HasGroup
bool HasGroup(const RegistryPath &group)
Definition: PluginManager.cpp:1662
PluginDescriptor::mEffectDefault
bool mEffectDefault
Definition: PluginManager.h:150
ComponentInterfaceSymbol::Msgid
const TranslatableString & Msgid() const
Definition: ComponentInterfaceSymbol.h:56
PluginManager::HasPrivateConfigGroup
bool HasPrivateConfigGroup(const PluginID &ID, const RegistryPath &group)
Definition: PluginManager.cpp:578
PluginDescriptor::mPluginType
PluginType mPluginType
Definition: PluginManager.h:134
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
PluginDescriptor::SetProviderID
void SetProviderID(const PluginID &providerID)
Definition: PluginManager.cpp:150
PluginManager::RemovePrivateConfig
bool RemovePrivateConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key) override
Definition: PluginManager.cpp:649
desc
const TranslatableString desc
Definition: ExportPCM.cpp:58
PluginDescriptor::PluginDescriptor
PluginDescriptor()
Definition: PluginManager.cpp:47
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
PluginManager::SettingsPath
RegistryPath SettingsPath(const PluginID &ID, bool shared)
Definition: PluginManager.cpp:1854
PluginDescriptor::SetImporterExtensions
void SetImporterExtensions(FileExtensions extensions)
Definition: PluginManager.cpp:275
PluginType
PluginType
Definition: PluginManager.h:32
PluginDescriptor::SetInstance
void SetInstance(std::unique_ptr< ComponentInterface > instance)
Definition: PluginManager.cpp:89
KEY_VENDOR
#define KEY_VENDOR
Definition: PluginManager.cpp:300
ComponentInterface::GetVendor
virtual VendorSymbol GetVendor()=0
ModuleInterface
Definition: ModuleInterface.h:70
ModuleManager::GetPluginTypeString
static wxString GetPluginTypeString()
Definition: ModuleManager.cpp:405
PluginManager::DropFile
bool DropFile(const wxString &fileName)
Definition: PluginManager.cpp:754
PluginDescriptor::SetSymbol
void SetSymbol(const ComponentInterfaceSymbol &symbol)
Definition: PluginManager.cpp:160
PluginDescriptor::GetVendor
wxString GetVendor() const
Definition: PluginManager.cpp:125
FileNames::PluginRegistry
FILES_API FilePath PluginRegistry()
PluginManager::~PluginManager
~PluginManager()
Definition: PluginManager.cpp:678
FileConfig::GetNextGroup
virtual bool GetNextGroup(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:108
KEY_EFFECTINTERACTIVE
#define KEY_EFFECTINTERACTIVE
Definition: PluginManager.cpp:310
PluginDescriptor::SetValid
void SetValid(bool valid)
Definition: PluginManager.cpp:180
PluginManager::Iterator::mPm
const PluginManager & mPm
Definition: PluginManager.h:269
PluginManager::Iterator
Definition: PluginManager.h:252
ModuleManager::IsProviderValid
bool IsProviderValid(const PluginID &provider, const PluginPath &path)
Definition: ModuleManager.cpp:524
PluginDescriptor::mPath
PluginPath mPath
Definition: PluginManager.h:137
ModuleManager
Definition: ModuleManager.h:71
KEY_NAME
#define KEY_NAME
Definition: PluginManager.cpp:299
KEY_PROVIDERID
#define KEY_PROVIDERID
Definition: PluginManager.cpp:306
PluginManager::SharedGroup
RegistryPath SharedGroup(const PluginID &ID, const RegistryPath &group)
Definition: PluginManager.cpp:1883
PluginDescriptor::mEffectInteractive
bool mEffectInteractive
Definition: PluginManager.h:149
PluginDescriptor::IsInstantiated
bool IsInstantiated() const
Definition: PluginManager.cpp:68
XPC
#define XPC(sing, plur, n, c)
Definition: Internat.h:100
ComponentInterface::GetPath
virtual PluginPath GetPath()=0
PluginManager.h
KEY_ENABLED
#define KEY_ENABLED
Definition: PluginManager.cpp:304
PluginManager::Iterator::mEffectType
EffectType mEffectType
Definition: PluginManager.h:271
AudacityFileConfig::Create
static std::unique_ptr< AudacityFileConfig > Create(const wxString &appName={}, const wxString &vendorName={}, const wxString &localFilename={}, const wxString &globalFilename={}, long style=wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_GLOBAL_FILE, const wxMBConv &conv=wxConvAuto())
Require a call to this factory, to guarantee proper two-phase initialization.
Definition: AudacityFileConfig.cpp:36
PluginID
wxString PluginID
Definition: EffectManager.h:30
PluginManager::SetPrivateConfig
bool SetPrivateConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key, const wxString &value) override
Definition: PluginManager.cpp:613
ModuleManager::Get
static ModuleManager & Get()
Definition: ModuleManager.cpp:395
PluginManager::mSettings
std::unique_ptr< FileConfig > mSettings
Definition: PluginManager.h:349
PluginDescriptor::GetUntranslatedVersion
wxString GetUntranslatedVersion() const
Definition: PluginManager.cpp:120
name
const TranslatableString name
Definition: Distortion.cpp:98
SETVERCUR
#define SETVERCUR
Definition: PluginManager.cpp:293
PluginTypeModule
@ PluginTypeModule
Definition: PluginManager.h:39
PluginManager::GetPrivateConfigSubgroups
bool GetPrivateConfigSubgroups(const PluginID &ID, const RegistryPath &group, RegistryPaths &subgroups) override
Definition: PluginManager.cpp:583
EffectTypeTool
@ EffectTypeTool
Definition: EffectInterface.h:61
SETROOT
#define SETROOT
Definition: PluginManager.cpp:294
AudacityFileConfig.h
PluginManager::Iterator::mIterator
PluginMap::iterator mIterator
Definition: PluginManager.h:270
PluginManager::Initialize
void Initialize()
Definition: PluginManager.cpp:705
PluginDescriptor::SetImporterIdentifier
void SetImporterIdentifier(const wxString &identifier)
Definition: PluginManager.cpp:264
PluginManager::GetPlugin
const PluginDescriptor * GetPlugin(const PluginID &ID) const
Definition: PluginManager.cpp:1445
PluginTypeAudacityCommand
@ PluginTypeAudacityCommand
Definition: PluginManager.h:36
PluginDescriptor
Definition: PluginManager.h:44
PluginDescriptor::mValid
bool mValid
Definition: PluginManager.h:143
EffectDefinitionInterface::GetType
virtual EffectType GetType()=0
PluginDescriptor::mID
wxString mID
Definition: PluginManager.h:136
EffectTypeHidden
@ EffectTypeHidden
Definition: EffectInterface.h:57
PluginManager::UnregisterPlugin
void UnregisterPlugin(const PluginID &ID)
Definition: PluginManager.cpp:1434
PluginManager::Load
void Load()
Load from preferences.
Definition: PluginManager.cpp:865
PluginDescriptor::SetEffectFamily
void SetEffectFamily(const wxString &family)
Definition: PluginManager.cpp:222
PluginDescriptor::mSymbol
ComponentInterfaceSymbol mSymbol
Definition: PluginManager.h:138
PluginManager::SaveGroup
void SaveGroup(FileConfig *pRegistry, PluginType type)
Definition: PluginManager.cpp:1241
KEY_EFFECTDEFAULT
#define KEY_EFFECTDEFAULT
Definition: PluginManager.cpp:309
PluginTypeNone
@ PluginTypeNone
Definition: PluginManager.h:33
KEY_EFFECTAUTOMATABLE
#define KEY_EFFECTAUTOMATABLE
Definition: PluginManager.cpp:312
RegistryPath
wxString RegistryPath
Definition: Identifier.h:218
EffectDefinitionInterface::GetClassification
virtual EffectType GetClassification()
Definition: EffectInterface.h:83
FileConfig
Definition: FileConfig.h:21
KEY_SYMBOL
#define KEY_SYMBOL
Definition: PluginManager.cpp:298
Internat.h
FileConfig::DeleteGroup
virtual bool DeleteGroup(const wxString &key) wxOVERRIDE
Definition: FileConfig.cpp:219
id
int id
Definition: WaveTrackControls.cpp:591
PluginManager::GetPrivateConfig
bool GetPrivateConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key, wxString &value, const wxString &defval=_T("")) override
Definition: PluginManager.cpp:588
PluginManager::GetPluginEnabledSetting
RegistryPath GetPluginEnabledSetting(const PluginID &ID) const
Definition: PluginManager.cpp:352
KEY_VERSION
#define KEY_VERSION
Definition: PluginManager.cpp:301
PluginDescriptor::GetID
const wxString & GetID() const
Definition: PluginManager.cpp:100
PluginManager::mInstance
static std::unique_ptr< PluginManager > mInstance
Definition: PluginManager.h:345
PluginManagerInterface::DefaultRegistrationCallback
static const PluginID & DefaultRegistrationCallback(ModuleInterface *provider, ComponentInterface *ident)
Definition: PluginManager.cpp:329
PluginDescriptor::mImporterIdentifier
wxString mImporterIdentifier
Definition: PluginManager.h:157
PluginManager::Get
static PluginManager & Get()
Definition: PluginManager.cpp:695
PluginManager::CreatePlugin
PluginDescriptor & CreatePlugin(const PluginID &id, ComponentInterface *ident, PluginType type)
Definition: PluginManager.cpp:1613
PluginDescriptor::GetEffectType
EffectType GetEffectType() const
Definition: PluginManager.cpp:192
PluginPaths
std::vector< PluginPath > PluginPaths
Definition: Identifier.h:215
PluginManager::EnablePlugin
void EnablePlugin(const PluginID &ID, bool enable)
Definition: PluginManager.cpp:1514
EffectDefinitionInterface
EffectDefinitionInterface is a ComponentInterface that additionally tracks flag-functions for interac...
Definition: EffectInterface.h:76
PluginManager::CheckForUpdates
void CheckForUpdates(bool bFast=false)
Definition: PluginManager.cpp:1327
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
PluginManager::b64encode
wxString b64encode(const void *in, int len)
Definition: PluginManager.cpp:1963
PluginTypeExporter
@ PluginTypeExporter
Definition: PluginManager.h:37
PlatformCompatibility.h
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: CommandManager.cpp:201
PluginDescriptor::IsEnabled
bool IsEnabled() const
Definition: PluginManager.cpp:130
PluginManager
PluginManager maintains a list of all plug ins. That covers modules, effects, generators,...
Definition: PluginManager.h:174
KEY_EFFECTREALTIME
#define KEY_EFFECTREALTIME
Definition: PluginManager.cpp:311
PluginDescriptor::SetEffectRealtime
void SetEffectRealtime(bool realtime)
Definition: PluginManager.cpp:247
PluginManager::Iterator::Advance
void Advance(bool incrementing)
Definition: PluginManager.cpp:1453
names
static TranslatableStrings names
Definition: Tags.cpp:744
KEY_EFFECTTYPE_ANALYZE
#define KEY_EFFECTTYPE_ANALYZE
Definition: PluginManager.cpp:314
PluginDescriptor::GetInstance
ComponentInterface * GetInstance()
Definition: PluginManager.cpp:73
PluginManager::GetID
static PluginID GetID(ModuleInterface *module)
Definition: PluginManager.cpp:1553
MemoryX.h
KEY_EFFECTTYPE
#define KEY_EFFECTTYPE
Definition: PluginManager.cpp:307
REGROOT
#define REGROOT
Definition: PluginManager.cpp:289
EffectTypeAnalyze
@ EffectTypeAnalyze
Definition: EffectInterface.h:60
PluginDescriptor::mEnabled
bool mEnabled
Definition: PluginManager.h:142
KEY_EFFECTTYPE_GENERATE
#define KEY_EFFECTTYPE_GENERATE
Definition: PluginManager.cpp:315
PluginDescriptor::GetImporterIdentifier
const wxString & GetImporterIdentifier() const
Definition: PluginManager.cpp:259
PluginManager::GetPluginCount
int GetPluginCount(PluginType type)
Definition: PluginManager.cpp:1439
FileNames.h
PluginDescriptor::mEffectRealtime
bool mEffectRealtime
Definition: PluginManager.h:152
AudacityMessageBox.h
PluginManager::IsPluginEnabled
bool IsPluginEnabled(const PluginID &ID)
Definition: PluginManager.cpp:1506
PluginDescriptor::SetEffectType
void SetEffectType(EffectType type)
Definition: PluginManager.cpp:227
PluginManager::PluginsOfType
Range PluginsOfType(int type)
Definition: PluginManager.h:281
KEY_DESCRIPTION
#define KEY_DESCRIPTION
Definition: PluginManager.cpp:302
ModuleInterface::GetOptionalFamilySymbol
virtual EffectFamilySymbol GetOptionalFamilySymbol()=0
PluginDescriptor::GetSymbol
const ComponentInterfaceSymbol & GetSymbol() const
Definition: PluginManager.cpp:115
ComponentInterfaceSymbol::Internal
const wxString & Internal() const
Definition: ComponentInterfaceSymbol.h:55
PluginDescriptor::IsEffectLegacy
bool IsEffectLegacy() const
Definition: PluginManager.cpp:207
Verbatim
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
Definition: TranslatableString.h:321
KEY_EFFECTTYPE_PROCESS
#define KEY_EFFECTTYPE_PROCESS
Definition: PluginManager.cpp:316
ExceptionType::Internal
@ Internal
Indicates internal failure from Audacity.
ComponentInterface
ComponentInterface provides name / vendor / version functions to identify plugins....
Definition: ComponentInterface.h:62
PluginDescriptor::~PluginDescriptor
virtual ~PluginDescriptor()
Definition: PluginManager.cpp:62
PluginDescriptor::IsEffectDefault
bool IsEffectDefault() const
Definition: PluginManager.cpp:202
PluginDescriptor::IsValid
bool IsValid() const
Definition: PluginManager.cpp:135
PluginDescriptor::SetEnabled
void SetEnabled(bool enable)
Definition: PluginManager.cpp:175
PluginDescriptor::SetVendor
void SetVendor(const wxString &vendor)
Definition: PluginManager.cpp:170
KEY_EFFECTTYPE_HIDDEN
#define KEY_EFFECTTYPE_HIDDEN
Definition: PluginManager.cpp:318
FileNames::DoCopyFile
FILES_API bool DoCopyFile(const FilePath &file1, const FilePath &file2, bool overwrite=true)
PluginDescriptor::mEffectAutomatable
bool mEffectAutomatable
Definition: PluginManager.h:153
PluginDescriptor::GetPath
const PluginPath & GetPath() const
Definition: PluginManager.cpp:110
REGVERCUR
#define REGVERCUR
Definition: PluginManager.cpp:288
PluginManager::RemoveSharedConfigSubgroup
bool RemoveSharedConfigSubgroup(const PluginID &ID, const RegistryPath &group) override
Definition: PluginManager.cpp:556
PluginDescriptor::SetVersion
void SetVersion(const wxString &version)
Definition: PluginManager.cpp:165
PluginDescriptor::SetEffectLegacy
void SetEffectLegacy(bool legacy)
Definition: PluginManager.cpp:242
PluginTypeStub
@ PluginTypeStub
Definition: PluginManager.h:34
ComponentInterface::GetName
TranslatableString GetName()
Definition: PluginManager.cpp:2083
PluginManager::Iterator::operator++
Iterator & operator++()
Definition: PluginManager.cpp:1500
PluginManager::ConvertID
wxString ConvertID(const PluginID &ID)
Definition: PluginManager.cpp:1936
PluginManager::GetSubgroups
bool GetSubgroups(const RegistryPath &group, RegistryPaths &subgroups)
Definition: PluginManager.cpp:1679
PluginManager::PrivateKey
RegistryPath PrivateKey(const PluginID &ID, const RegistryPath &group, const RegistryPath &key)
Definition: PluginManager.cpp:1923
ModuleManager::CreateProviderInstance
ModuleInterface * CreateProviderInstance(const PluginID &provider, const PluginPath &path)
Definition: ModuleManager.cpp:503
EffectType
EffectType
Definition: EffectInterface.h:55
safenew
#define safenew
Definition: MemoryX.h:10
settings
static Settings & settings()
Definition: TrackInfo.cpp:86
PluginManager::LoadGroup
void LoadGroup(FileConfig *pRegistry, PluginType type)
Definition: PluginManager.cpp:953
KEY_EFFECTTYPE_TOOL
#define KEY_EFFECTTYPE_TOOL
Definition: PluginManager.cpp:317
PluginManager::PrivateGroup
RegistryPath PrivateGroup(const PluginID &ID, const RegistryPath &group)
Definition: PluginManager.cpp:1909
EffectDefinitionInterface::GetFamily
virtual EffectFamilySymbol GetFamily()=0
PluginDescriptor::mImporterExtensions
FileExtensions mImporterExtensions
Definition: PluginManager.h:158
PluginManager::Terminate
void Terminate()
Definition: PluginManager.cpp:730
PlatformCompatibility::GetExecutablePath
static const FilePath & GetExecutablePath()
Definition: PlatformCompatibility.cpp:33
PluginDescriptor::mEffectType
EffectType mEffectType
Definition: PluginManager.h:148
KEY_VALID
#define KEY_VALID
Definition: PluginManager.cpp:305
ArrayOf< char >
REGVERKEY
#define REGVERKEY
Definition: PluginManager.cpp:287
PluginDescriptor::SetEffectDefault
void SetEffectDefault(bool dflt)
Definition: PluginManager.cpp:237
PluginManager::SetSharedConfig
bool SetSharedConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key, const wxString &value) override
Definition: PluginManager.cpp:531
PluginManager::HasSharedConfigGroup
bool HasSharedConfigGroup(const PluginID &ID, const RegistryPath &group)
Definition: PluginManager.cpp:496
PluginTypeImporter
@ PluginTypeImporter
Definition: PluginManager.h:38
EffectDefinitionInterface::IsDefault
virtual bool IsDefault()=0
PluginDescriptor::SetPluginType
void SetPluginType(PluginType type)
Definition: PluginManager.cpp:140
PluginDescriptor::SetID
void SetID(const PluginID &ID)
Definition: PluginManager.cpp:145
PluginDescriptor::mEffectFamily
wxString mEffectFamily
Definition: PluginManager.h:147
PluginManager::GetSettings
FileConfig * GetSettings()
Definition: PluginManager.cpp:1631
PluginManager::SetConfig
bool SetConfig(const RegistryPath &key, const wxString &value)
Definition: PluginManager.cpp:1772
padc
static const char padc
Definition: PluginManager.cpp:1961
FileConfig::GetPath
virtual const wxString & GetPath() const wxOVERRIDE
Definition: FileConfig.cpp:98