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