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/setup.h> // for wxUSE_* macros
29 #include <wx/defs.h>
30 #include <wx/dialog.h>
31 #include <wx/dir.h>
32 #include <wx/dynlib.h>
33 #include <wx/filename.h>
34 #include <wx/listctrl.h>
35 #include <wx/log.h>
36 #include <wx/radiobut.h>
37 #include <wx/string.h>
38 #include <wx/tokenzr.h>
39 #include <wx/wfstream.h>
40 #include <wx/utils.h>
41 
44 
45 #include "AudacityFileConfig.h"
46 #include "FileNames.h"
47 #include "ModuleManager.h"
48 #include "PlatformCompatibility.h"
49 #include "Prefs.h"
50 #include "ShuttleGui.h"
51 #include "wxFileNameWrapper.h"
53 #include "widgets/ProgressDialog.h"
54 
55 #include <unordered_map>
56 
57 // ============================================================================
58 //
59 //
60 //
61 // ============================================================================
62 #if wxUSE_ACCESSIBILITY
64 
65 class CheckListAx final : public WindowAccessible
66 {
67 public:
68  CheckListAx(wxListCtrl * window);
69 
70  virtual ~ CheckListAx();
71 
72  // Retrieves the address of an IDispatch interface for the specified child.
73  // All objects must support this property.
74  wxAccStatus GetChild( int childId, wxAccessible **child ) override;
75 
76  // Gets the number of children.
77  wxAccStatus GetChildCount( int *childCount ) override;
78 
79  // Gets the default action for this object (0) or > 0 (the action for a child).
80  // Return wxACC_OK even if there is no action. actionName is the action, or the empty
81  // string if there is no action.
82  // The retrieved string describes the action that is performed on an object,
83  // not what the object does as a result. For example, a toolbar button that prints
84  // a document has a default action of "Press" rather than "Prints the current document."
85  wxAccStatus GetDefaultAction( int childId, wxString *actionName ) override;
86 
87  // Returns the description for this object or a child.
88  wxAccStatus GetDescription( int childId, wxString *description ) override;
89 
90  // Gets the window with the keyboard focus.
91  // If childId is 0 and child is NULL, no object in
92  // this subhierarchy has the focus.
93  // If this object has the focus, child should be 'this'.
94  wxAccStatus GetFocus( int *childId, wxAccessible **child ) override;
95 
96  // Returns help text for this object or a child, similar to tooltip text.
97  wxAccStatus GetHelpText( int childId, wxString *helpText ) override;
98 
99  // Returns the keyboard shortcut for this object or child.
100  // Return e.g. ALT+K
101  wxAccStatus GetKeyboardShortcut( int childId, wxString *shortcut ) override;
102 
103  // Returns the rectangle for this object (id = 0) or a child element (id > 0).
104  // rect is in screen coordinates.
105  wxAccStatus GetLocation( wxRect& rect, int elementId ) override;
106 
107  // Gets the name of the specified object.
108  wxAccStatus GetName( int childId, wxString *name ) override;
109 
110  // Returns a role constant.
111  wxAccStatus GetRole( int childId, wxAccRole *role ) override;
112 
113  // Gets a variant representing the selected children
114  // of this object.
115  // Acceptable values:
116  // - a null variant (IsNull() returns TRUE)
117  // - a list variant (GetType() == wxT("list"))
118  // - an integer representing the selected child element,
119  // or 0 if this object is selected (GetType() == wxT("long"))
120  // - a "void*" pointer to a wxAccessible child object
121  wxAccStatus GetSelections( wxVariant *selections ) override;
122 
123  // Returns a state constant.
124  wxAccStatus GetState( int childId, long* state ) override;
125 
126  // Returns a localized string representing the value for the object
127  // or child.
128  wxAccStatus GetValue( int childId, wxString *strValue ) override;
129 
130  void SetSelected( int item, bool focused = true );
131 
132 private:
133  wxListCtrl *mParent;
134  int mLastId;
135 };
136 
137 CheckListAx::CheckListAx( wxListCtrl * window )
138 : WindowAccessible( window )
139 {
140  mParent = window;
141  mLastId = -1;
142 }
143 
144 CheckListAx::~CheckListAx()
145 {
146 }
147 
148 void CheckListAx::SetSelected( int item, bool focused )
149 {
150  if (mLastId != -1)
151  {
152  NotifyEvent( wxACC_EVENT_OBJECT_SELECTIONREMOVE,
153  mParent,
154  wxOBJID_CLIENT,
155  mLastId );
156  mLastId = -1;
157  }
158 
159  if (item != -1)
160  {
161  if (focused)
162  {
163  NotifyEvent( wxACC_EVENT_OBJECT_FOCUS,
164  mParent,
165  wxOBJID_CLIENT,
166  item + 1 );
167  }
168 
169  NotifyEvent( wxACC_EVENT_OBJECT_SELECTION,
170  mParent,
171  wxOBJID_CLIENT,
172  item + 1 );
173 
174  mLastId = item + 1;
175  }
176 }
177 
178 // Retrieves the address of an IDispatch interface for the specified child.
179 // All objects must support this property.
180 wxAccStatus CheckListAx::GetChild( int childId, wxAccessible** child )
181 {
182  if( childId == wxACC_SELF )
183  {
184  *child = this;
185  }
186  else
187  {
188  *child = NULL;
189  }
190 
191  return wxACC_OK;
192 }
193 
194 // Gets the number of children.
195 wxAccStatus CheckListAx::GetChildCount( int *childCount )
196 {
197  *childCount = mParent->GetItemCount();
198 
199  return wxACC_OK;
200 }
201 
202 // Gets the default action for this object (0) or > 0 (the action for a child).
203 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
204 // string if there is no action.
205 // The retrieved string describes the action that is performed on an object,
206 // not what the object does as a result. For example, a toolbar button that prints
207 // a document has a default action of "Press" rather than "Prints the current document."
208 wxAccStatus CheckListAx::GetDefaultAction( int WXUNUSED(childId), wxString *actionName )
209 {
210  actionName->clear();
211 
212  return wxACC_OK;
213 }
214 
215 // Returns the description for this object or a child.
216 wxAccStatus CheckListAx::GetDescription( int WXUNUSED(childId), wxString *description )
217 {
218  description->clear();
219 
220  return wxACC_OK;
221 }
222 
223 // Gets the window with the keyboard focus.
224 // If childId is 0 and child is NULL, no object in
225 // this subhierarchy has the focus.
226 // If this object has the focus, child should be 'this'.
227 wxAccStatus CheckListAx::GetFocus( int *childId, wxAccessible **child )
228 {
229  *childId = 0;
230  *child = this;
231 
232  return wxACC_OK;
233 }
234 
235 // Returns help text for this object or a child, similar to tooltip text.
236 wxAccStatus CheckListAx::GetHelpText( int WXUNUSED(childId), wxString *helpText )
237 {
238  helpText->clear();
239 
240  return wxACC_OK;
241 }
242 
243 // Returns the keyboard shortcut for this object or child.
244 // Return e.g. ALT+K
245 wxAccStatus CheckListAx::GetKeyboardShortcut( int WXUNUSED(childId), wxString *shortcut )
246 {
247  shortcut->clear();
248 
249  return wxACC_OK;
250 }
251 
252 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
253 // rect is in screen coordinates.
254 wxAccStatus CheckListAx::GetLocation( wxRect& rect, int elementId )
255 {
256  if( elementId == wxACC_SELF )
257  {
258  rect = mParent->GetRect();
259  rect.SetPosition( mParent->GetParent()->ClientToScreen( rect.GetPosition() ) );
260  }
261  else
262  {
263  if( elementId <= mParent->GetItemCount() )
264  {
265  mParent->GetItemRect( elementId - 1, rect, wxLIST_RECT_LABEL );
266  rect.SetPosition( mParent->ClientToScreen( rect.GetPosition() ) );
267  }
268  }
269 
270  return wxACC_OK;
271 }
272 
273 // Gets the name of the specified object.
274 wxAccStatus CheckListAx::GetName( int WXUNUSED(childId), wxString *name )
275 {
276  *name = mParent->GetName();
277 
278  return wxACC_OK;
279 }
280 
281 // Returns a role constant.
282 wxAccStatus CheckListAx::GetRole( int childId, wxAccRole *role )
283 {
284  if( childId == wxACC_SELF )
285  {
286  *role = wxROLE_SYSTEM_LIST;
287  }
288  else
289  {
290  *role = wxROLE_SYSTEM_LISTITEM;
291  }
292 
293  return wxACC_OK;
294 }
295 
296 // Gets a variant representing the selected children
297 // of this object.
298 // Acceptable values:
299 // - a null variant (IsNull() returns TRUE)
300 // - a list variant (GetType() == wxT("list"))
301 // - an integer representing the selected child element,
302 // or 0 if this object is selected (GetType() == wxT("long"))
303 // - a "void*" pointer to a wxAccessible child object
304 wxAccStatus CheckListAx::GetSelections( wxVariant * WXUNUSED(selections) )
305 {
306  return wxACC_NOT_IMPLEMENTED;
307 }
308 
309 // Returns a state constant.
310 wxAccStatus CheckListAx::GetState( int childId, long *pState )
311 {
312  int flag = wxACC_STATE_SYSTEM_FOCUSABLE;
313 
314  if( childId == wxACC_SELF )
315  {
316  flag |= wxACC_STATE_SYSTEM_FOCUSED;
317  }
318  else
319  {
320  wxListItem item;
321 
322  item.SetId( childId - 1 );
323  item.SetState( wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED );
324  item.SetMask( wxLIST_MASK_STATE );
325 
326  if( mParent->GetItem( item ) )
327  {
328  flag |= wxACC_STATE_SYSTEM_SELECTABLE;
329 
330  long state = item.GetState();
331 
332  if( state & wxLIST_STATE_FOCUSED )
333  {
334  flag |= wxACC_STATE_SYSTEM_FOCUSED;
335  }
336 
337  if( state & wxLIST_STATE_SELECTED )
338  {
339  flag |= wxACC_STATE_SYSTEM_SELECTED;
340  }
341  }
342  }
343 
344  *pState = flag;
345 
346  return wxACC_OK;
347 }
348 
349 // Returns a localized string representing the value for the object
350 // or child.
351 wxAccStatus CheckListAx::GetValue( int childId, wxString *strValue )
352 {
353  if( childId == 0 )
354  {
355  return wxACC_OK;
356  }
357  else
358  {
359  *strValue = mParent->GetItemText( childId - 1 );
360  }
361 
362  return wxACC_OK;
363 }
364 
365 #endif
366 
367 // ============================================================================
368 //
369 //
370 //
371 // ============================================================================
372 
373 enum
374 {
378 
380 };
381 
382 struct ItemData
383 {
384  std::vector<PluginDescriptor*> plugs;
385  wxString name;
387  int state;
388  bool valid;
392 };
393 
394 using ItemDataMap = std::unordered_map<PluginPath, ItemData>;
395 
396 enum
397 {
398  ID_ShowAll = 10000,
407 };
408 
409 enum
410 {
414 
415  COL_COUNT
416 };
417 
419 {
420 public:
421  // constructors and destructors
422  PluginRegistrationDialog(wxWindow *parent, EffectType type);
423 
424 private:
425  void Populate();
426  void PopulateOrExchange(ShuttleGui & S);
427  void RegenerateEffectsList(int iShowWhat);
428  void SetState(int i, bool toggle, bool state = true);
429 
430  static int wxCALLBACK SortCompare(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData);
431  int SortCompare(ItemData *item1, ItemData *item2);
432 
433  void OnChangedVisibility(wxCommandEvent & evt);
434  void OnSort(wxListEvent & evt);
435  void DoSort( int col );
436  void OnListChar(wxKeyEvent & evt);
437  void OnOK(wxCommandEvent & evt);
438  void OnCancel(wxCommandEvent & evt);
439  void OnSelectAll(wxCommandEvent & evt);
440  void OnClearAll(wxCommandEvent & evt);
441  void OnEnable(wxCommandEvent & evt);
442  void OnDisable(wxCommandEvent & evt);
443 
444 private:
446  int mFilter;
447 
448  wxArrayString mStates;
450 
453 
455 
456  wxListCtrl *mEffects;
457 #if wxUSE_ACCESSIBILITY
458  CheckListAx *mAx;
459 #endif
460 
461  DECLARE_EVENT_TABLE()
462 };
463 
464 BEGIN_EVENT_TABLE(PluginRegistrationDialog, wxDialogWrapper)
465  EVT_LIST_COL_CLICK(ID_List, PluginRegistrationDialog::OnSort)
477 
479 : wxDialogWrapper(parent,
480  wxID_ANY,
481  XO("Manage Plug-ins"),
482  wxDefaultPosition, wxDefaultSize,
483  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
484 {
485  mType = type;
486  mEffects = NULL;
487  SetName();
488 
489  mStates.resize(STATE_COUNT);
490  mStates[STATE_Enabled] = _("Enabled");
491  mStates[STATE_Disabled] = _("Disabled");
492  mStates[STATE_New] = _("New");
493 
494  mSortColumn = COL_Name;
495  mSortDirection = 1;
496 
497  Populate();
498 
499  DoSort( mSortColumn );
500 }
501 
503 {
504  //------------------------- Main section --------------------
505  ShuttleGui S(this, eIsCreating);
507  // ----------------------- End of main section --------------
508 }
509 
512 {
513  S.StartVerticalLay(true);
514  {
515  /*i18n-hint: The dialog shows a list of plugins with check-boxes
516  beside each one.*/
517 // S.StartStatic(XO("Effects"), true);
518  S.StartVerticalLay();
519  {
520  S.StartHorizontalLay(wxEXPAND, 0);
521  {
522  S.StartHorizontalLay(wxALIGN_LEFT, 0);
523  {
524  S.AddPrompt(XXO("Select effects, click the Enable or Disable button, then click OK."));
525  }
526  S.EndHorizontalLay();
527 
528  S.StartHorizontalLay(wxCENTER, 1);
529  {
530  S.AddSpace(1);
531  }
532  S.EndHorizontalLay();
533 
534  S.StartHorizontalLay(wxALIGN_NOT | wxALIGN_LEFT, 0);
535  {
536  wxRadioButton *rb;
537 
538  /* i18n-hint: This is before radio buttons selecting which effects to show */
539  S.AddPrompt(XXO("Show:"));
540  rb = S.Id(ID_ShowAll)
541  /* i18n-hint: Radio button to show all effects */
542  .Name(XO("Show all"))
543  /* i18n-hint: Radio button to show all effects */
544  .AddRadioButton(XXO("&All"));
545 #if wxUSE_ACCESSIBILITY
546  // so that name can be set on a standard control
547  rb->SetAccessible(safenew WindowAccessible(rb));
548 #endif
549 
550  rb = S.Id(ID_ShowDisabled)
551  /* i18n-hint: Radio button to show just the currently disabled effects */
552  .Name(XO("Show disabled"))
553  /* i18n-hint: Radio button to show just the currently disabled effects */
554  .AddRadioButtonToGroup(XXO("D&isabled"));
555 #if wxUSE_ACCESSIBILITY
556  // so that name can be set on a standard control
557  rb->SetAccessible(safenew WindowAccessible(rb));
558 #endif
559 
560  rb = S.Id(ID_ShowEnabled)
561  /* i18n-hint: Radio button to show just the currently enabled effects */
562  .Name(XO("Show enabled"))
563  /* i18n-hint: Radio button to show just the currently enabled effects */
564  .AddRadioButtonToGroup(XXO("E&nabled"));
565 #if wxUSE_ACCESSIBILITY
566  // so that name can be set on a standard control
567  rb->SetAccessible(safenew WindowAccessible(rb));
568 #endif
569 
570  rb = S.Id(ID_ShowNew)
571  /* i18n-hint: Radio button to show just the newly discovered effects */
572  .Name(XO("Show new"))
573  /* i18n-hint: Radio button to show just the newly discovered effects */
574  .AddRadioButtonToGroup(XXO("Ne&w"));
575 #if wxUSE_ACCESSIBILITY
576  // so that name can be set on a standard control
577  rb->SetAccessible(safenew WindowAccessible(rb));
578 #endif
579  }
580  S.EndHorizontalLay();
581  }
582  S.EndHorizontalLay();
583 
584  mEffects = S.Id(ID_List)
585  .Style(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES )
586  .ConnectRoot(wxEVT_KEY_DOWN,
588  .AddListControlReportMode({ XO("Name"), XO("State"), XO("Path") });
589 #if wxUSE_ACCESSIBILITY
590  mEffects->SetAccessible(mAx = safenew CheckListAx(mEffects));
591 #endif
592 
593  S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND, 0);
594  {
595  S.Id(ID_SelectAll).AddButton(XXO("&Select All"));
596  S.Id(ID_ClearAll).AddButton(XXO("C&lear All"));
597 
598  S.StartHorizontalLay(wxALIGN_CENTER);
599  {
600  S.AddSpace(1);
601  }
602  S.EndHorizontalLay();
603 
604  S.Id(ID_Enable).AddButton(XXO("&Enable"));
605  S.Id(ID_Disable).AddButton(XXO("&Disable"));
606  }
607  S.EndHorizontalLay();
608  }
609 // S.EndStatic();
610  S.EndVerticalLay();
611 
613  }
614  S.EndVerticalLay();
615 
616  std::vector<int> colWidths;
617  for (int i = 0, cnt = mEffects->GetColumnCount(); i < cnt; i++)
618  {
619  colWidths.push_back(0);
620  }
621 
622  for (int i = 0, cnt = mStates.size(); i < cnt; i++)
623  {
624  int x;
625  mEffects->GetTextExtent(mStates[i], &x, NULL);
626  colWidths[COL_State] = wxMax(colWidths[COL_State], x + 4); // 2 pixel margin on each side
627  }
628 
630  for (PluginMap::iterator iter = pm.mPlugins.begin(); iter != pm.mPlugins.end(); ++iter)
631  {
632  PluginDescriptor & plug = iter->second;
633 
634  PluginType plugType = plug.GetPluginType();
635  if (plugType != PluginTypeEffect && plugType != PluginTypeStub)
636  {
637  continue;
638  }
639 
640  const auto &path = plug.GetPath();
641  ItemData & item = mItems[path]; // will create NEW entry
642  item.plugs.push_back(&plug);
643  item.path = path;
644  item.state = plug.IsEnabled() ? STATE_Enabled : STATE_Disabled;
645  item.valid = plug.IsValid();
646 
647  if (plugType == PluginTypeEffect)
648  {
649  item.name = plug.GetSymbol().Translation();
650  }
651  // This is not right and will not work when other plugin types are added.
652  // But it's presumed that the plugin manager dialog will be fully developed
653  // by then.
654  else if (plugType == PluginTypeStub)
655  {
656  wxFileName fname { path };
657  item.name = fname.GetName().Trim(false).Trim(true);
658  if (!item.valid)
659  {
660  item.state = STATE_New;
661  }
662  }
663 
664  int x;
665  mEffects->GetTextExtent(item.name, &x, NULL);
666  colWidths[COL_Name] = wxMax(colWidths[COL_Name], x);
667 
668  mEffects->GetTextExtent(item.path, &x, NULL);
669  if (x > colWidths[COL_Path])
670  {
671  mLongestPath = item.path;
672  }
673  colWidths[COL_Path] = wxMax(colWidths[COL_Path], x);
674  }
675 
676  wxRect r = wxGetClientDisplayRect();
677 
678  int maxW = 0;
679  for (int i = 0, cnt = mEffects->GetColumnCount(); i < cnt; i++)
680  {
681  int w = colWidths[i] + /* fudge */ 10;
682  mEffects->SetColumnWidth(i, w);
683  maxW += w;
684  }
685 
686  // Keep dialog from getting too wide
687  int w = r.GetWidth() - (GetClientSize().GetWidth() - mEffects->GetSize().GetWidth());
688  mEffects->SetMinSize({ std::min(maxW, w), 200 });
689  mEffects->SetMaxSize({ w, -1 });
690 
692 
693  Layout();
694  Fit();
695 
696  wxSize sz = GetSize();
697  sz.SetWidth(wxMin(sz.GetWidth(), r.GetWidth()));
698  sz.SetHeight(wxMin(sz.GetHeight(), r.GetHeight()));
699  SetMinSize(sz);
700 
701  // Parent window is usually not there yet, so centre on screen rather than on parent.
702  CenterOnScreen();
703 
704  if (mEffects->GetItemCount() > 0)
705  {
706  // Make sure first item is selected/focused.
707  mEffects->SetFocus();
708  mEffects->SetItemState(0, wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED, wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED);
709 #if wxUSE_ACCESSIBILITY
710  mAx->SetSelected(0);
711 #endif
712  }
713 
714 }
715 
717 {
718  mFilter = filter;
719 
720  mEffects->DeleteAllItems();
721 
722  int i = 0;
723  for (ItemDataMap::iterator iter = mItems.begin(); iter != mItems.end(); ++iter)
724  {
725  ItemData & item = iter->second;
726  bool add = false;
727 
728  switch (mFilter)
729  {
730  case ID_ShowAll:
731  add = true;
732  break;
733  case ID_ShowNew:
734  if (item.state == STATE_New)
735  {
736  add = true;
737  }
738  break;
739  case ID_ShowEnabled:
740  if (item.state == STATE_Enabled)
741  {
742  add = true;
743  }
744  break;
745  case ID_ShowDisabled:
746  if (item.state == STATE_Disabled)
747  {
748  add = true;
749  }
750  break;
751  }
752 
753  if (add)
754  {
755  mEffects->InsertItem(i, item.name);
756  mEffects->SetItem(i, COL_State, mStates[item.state]);
757  mEffects->SetItem(i, COL_Path, item.path);
758  mEffects->SetItemPtrData(i, (wxUIntPtr) &item);
759 
760  ++i;
761  }
762  }
763 
764  mEffects->SortItems(SortCompare, (wxUIntPtr) this);
765 
766  if (mEffects->GetItemCount() > 0)
767  {
768  // Make sure first item is selected/focused.
769 // mEffects->SetFocus();
770  mEffects->SetItemState(0, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED);
771 #if wxUSE_ACCESSIBILITY
772  mAx->SetSelected(0, false);
773 #endif
774  }
775 }
776 
777 void PluginRegistrationDialog::SetState(int i, bool toggle, bool state)
778 {
779  wxListItem li;
780 
781  li.m_mask = wxLIST_MASK_DATA;
782  li.m_itemId = i;
783 
784  mEffects->GetItem(li);
785 
786  ItemData *item = (ItemData *) li.m_data;
787 
788  // If changing the state of a "New" (stub) entry, then we mark it as valid
789  // since it will either be registered if "Enabled" or ignored if "Disabled".
790  if (item->state == STATE_New)
791  {
792  item->valid = true;
793  }
794 
795  if (toggle)
796  {
798  }
799  else
800  {
801  item->state = state;
802  }
803 
804  if (mFilter == ID_ShowNew && item->state != STATE_New)
805  {
806  mEffects->DeleteItem(i);
807  }
808  else if (mFilter == ID_ShowDisabled && item->state != STATE_Disabled)
809  {
810  mEffects->DeleteItem(i);
811  }
812  else if (mFilter == ID_ShowEnabled && item->state != STATE_Enabled)
813  {
814  mEffects->DeleteItem(i);
815  }
816  else
817  {
818  mEffects->SetItem(i, COL_State, mStates[item->state]);
819 #if wxUSE_ACCESSIBILITY
820  mAx->SetSelected(i);
821 #endif
822  }
823 }
824 
825 int wxCALLBACK PluginRegistrationDialog::SortCompare(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
826 {
828  ItemData *i1 = (ItemData *) item1;
829  ItemData *i2 = (ItemData *) item2;
830 
831  return dlg->SortCompare(i1, i2);
832 }
833 
835 {
836  // This function is a three-valued comparator
837 
838  wxString *str1;
839  wxString *str2;
840 
841  switch (mSortColumn)
842  {
843  case COL_Name:
844  str1 = &item1->name;
845  str2 = &item2->name;
846  break;
847  case COL_State:
848  str1 = &mStates[item1->state];
849  str2 = &mStates[item2->state];
850  break;
851  case COL_Path:
852  str1 = &item1->path;
853  str2 = &item2->path;
854  break;
855  default:
856  return 0;
857  }
858 
859  return str2->CmpNoCase(*str1) * mSortDirection;
860 }
861 
863 {
864  // Go and show the relevant items.
865  RegenerateEffectsList(evt.GetId());
866 }
867 
868 void PluginRegistrationDialog::OnSort(wxListEvent & evt)
869 {
870  int col = evt.GetColumn();
871  DoSort( col );
872 }
873 
875 {
876  if (col != mSortColumn)
877  {
878  mSortDirection = 1;
879  }
880  else
881  {
882  mSortDirection *= -1;
883  }
884 
885  mSortColumn = col;
886  mEffects->SortItems(SortCompare, (wxUIntPtr) this);
887 
888  // Without a refresh, wxMac doesn't redisplay the list properly after a sort
889  mEffects->Refresh();
890 }
891 
893 {
894  switch (evt.GetKeyCode())
895  {
896  case WXK_SPACE:
897  {
898  int item = mEffects->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED);
899  if (item != wxNOT_FOUND)
900  {
901  SetState(item, true);
902  }
903  }
904  break;
905 
906  case WXK_RETURN:
907  // Don't know why wxListCtrls prevent default dialog action,
908  // but they do, so handle it.
909  EmulateButtonClickIfPresent(GetAffirmativeId());
910  break;
911 
912  default:
913  evt.Skip();
914  break;
915  }
916 }
917 
918 void PluginRegistrationDialog::OnSelectAll(wxCommandEvent & WXUNUSED(evt))
919 {
920  for (int i = 0, cnt = mEffects->GetItemCount(); i < cnt; i++)
921  {
922  mEffects->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
923  }
924 }
925 
926 void PluginRegistrationDialog::OnClearAll(wxCommandEvent & WXUNUSED(evt))
927 {
928  for (int i = 0, cnt = mEffects->GetItemCount(); i < cnt; i++)
929  {
930  mEffects->SetItemState(i, 0, wxLIST_STATE_SELECTED);
931  }
932 }
933 
934 void PluginRegistrationDialog::OnEnable(wxCommandEvent & WXUNUSED(evt))
935 {
936  std::vector<long> items;
937 
938  {
939  long i = mEffects->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
940  while (i != wxNOT_FOUND)
941  {
942  items.insert(items.begin(), i);
943  i = mEffects->GetNextItem(i, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
944  }
945  }
946 
947  for (size_t i = 0, cnt = items.size(); i < cnt; i++)
948  {
949  SetState(items[i], false, STATE_Enabled);
950  }
951 }
952 
953 void PluginRegistrationDialog::OnDisable(wxCommandEvent & WXUNUSED(evt))
954 {
955  std::vector<long> items;
956 
957  {
958  long i = mEffects->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
959  while (i != wxNOT_FOUND)
960  {
961  items.insert(items.begin(), i);
962  i = mEffects->GetNextItem(i, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
963  }
964  }
965 
966  for (size_t i = 0, cnt = items.size(); i < cnt; i++)
967  {
968  SetState(items[i], false, STATE_Disabled);
969  }
970 }
971 
972 void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
973 {
976 
977  int enableCount = 0;
978  for (ItemDataMap::iterator iter = mItems.begin(); iter != mItems.end(); ++iter)
979  {
980  ItemData & item = iter->second;
981  wxString path = item.path;
982 
983  if (item.state == STATE_Enabled && item.plugs[0]->GetPluginType() == PluginTypeStub)
984  {
985  enableCount++;
986  }
987  }
988 
989  wxString last3 = mLongestPath + wxT("\n") +
990  mLongestPath + wxT("\n") +
991  mLongestPath + wxT("\n");
992 
993  auto msg = XO("Enabling effects or commands:\n\n%s").Format( last3 );
994 
995  // Make sure the progress dialog is deleted before we call EndModal() or
996  // we will leave the project window in an unusable state on OSX.
997  // See bug #1192.
998  {
999  ProgressDialog progress{
1000  Verbatim( GetTitle() ), msg, pdlgHideStopButton };
1001  progress.CenterOnParent();
1002 
1003  int i = 0;
1004  for (ItemDataMap::iterator iter = mItems.begin(); iter != mItems.end(); ++iter)
1005  {
1006  ItemData & item = iter->second;
1007  wxString path = item.path;
1008 
1009  if (item.state == STATE_Enabled && item.plugs[0]->GetPluginType() == PluginTypeStub)
1010  {
1011  last3 = last3.AfterFirst(wxT('\n')) + item.path + wxT("\n");
1012  auto status = progress.Update(++i, enableCount,
1013  XO("Enabling effect or command:\n\n%s").Format( last3 ));
1014  if (status == ProgressResult::Cancelled)
1015  {
1016  break;
1017  }
1018 
1019  TranslatableString errMsgs;
1020 
1021  // Try to register the plugin via each provider until one succeeds
1022  for (size_t j = 0, cntj = item.plugs.size(); j < cntj; j++)
1023  {
1024  TranslatableString errMsg;
1025  if (mm.RegisterEffectPlugin(item.plugs[j]->GetProviderID(), path,
1026  errMsg))
1027  {
1028  for (size_t k = 0, cntk = item.plugs.size(); k < cntk; k++)
1029  {
1030  pm.mPlugins.erase(item.plugs[k]->GetProviderID() + wxT("_") + path);
1031  }
1032  // Bug 1893. We've found a provider that works.
1033  // Error messages from any that failed are no longer useful.
1034  errMsgs = {};
1035  break;
1036  }
1037  else
1038  {
1039  if (!errMsgs.empty())
1040  errMsgs.Join( errMsg, '\n' );
1041  else
1042  errMsgs = errMsg;
1043  }
1044  }
1045  if (!errMsgs.empty())
1047  XO("Effect or Command at %s failed to register:\n%s")
1048  .Format( path, errMsgs ) );
1049  }
1050  else if (item.state == STATE_New)
1051  {
1052  for (size_t j = 0, cnt = item.plugs.size(); j < cnt; j++)
1053  {
1054  item.plugs[j]->SetValid(false);
1055  }
1056  }
1057  else if (item.state != STATE_New)
1058  {
1059  for (size_t j = 0, cnt = item.plugs.size(); j < cnt; j++)
1060  {
1061  item.plugs[j]->SetEnabled(item.state == STATE_Enabled);
1062  item.plugs[j]->SetValid(item.valid);
1063  }
1064  }
1065  }
1066 
1067  pm.Save();
1068  }
1069 
1070  EndModal(wxID_OK);
1071 }
1072 
1073 void PluginRegistrationDialog::OnCancel(wxCommandEvent & WXUNUSED(evt))
1074 {
1075  EndModal(wxID_CANCEL);
1076 }
1077 
1078 
1079 
1081 //
1082 // Plugindescriptor
1083 //
1085 
1087 {
1089  mEnabled = false;
1090  mValid = false;
1091  mInstance = NULL;
1092 
1094  mEffectInteractive = false;
1095  mEffectDefault = false;
1096  mEffectLegacy = false;
1097  mEffectRealtime = false;
1098  mEffectAutomatable = false;
1099 }
1100 
1102 {
1103  DeleteInstance();
1104 }
1105 
1107 {
1108  if (mInstance)
1109  {
1111  mInstance = nullptr;
1112  }
1113 }
1114 
1116 {
1117  return mInstance != NULL;
1118 }
1119 
1121 {
1122  if (!mInstance)
1123  {
1125  {
1127  }
1128  else
1129  {
1131  }
1132  }
1133 
1134  return mInstance;
1135 }
1136 
1138 {
1139  if (mInstance && mInstance != instance)
1140  {
1141  // Be sure not to leak resources!!
1142  DeleteInstance();
1143  }
1144 
1145  mInstance = instance;
1146 
1147  return;
1148 }
1149 
1151 {
1152  return mPluginType;
1153 }
1154 
1156 {
1157  return mID;
1158 }
1159 
1161 {
1162  return mProviderID;
1163 }
1164 
1166 {
1167  return mPath;
1168 }
1169 
1171 {
1172  return mSymbol;
1173 }
1174 
1176 {
1177  return mVersion;
1178 }
1179 
1181 {
1182  return mVendor;
1183 }
1184 
1186 {
1187  return mEnabled;
1188 }
1189 
1191 {
1192  return mValid;
1193 }
1194 
1196 {
1197  mPluginType = type;
1198 }
1199 
1201 {
1202  mID = ID;
1203 }
1204 
1206 {
1207  mProviderID = providerID;
1208 }
1209 
1211 {
1212  mPath = path;
1213 }
1214 
1216 {
1217  mSymbol = symbol;
1218 }
1219 
1220 void PluginDescriptor::SetVersion(const wxString & version)
1221 {
1222  mVersion = version;
1223 }
1224 
1225 void PluginDescriptor::SetVendor(const wxString & vendor)
1226 {
1227  mVendor = vendor;
1228 }
1229 
1231 {
1232  mEnabled = enable;
1233 }
1234 
1236 {
1237  mValid = valid;
1238 }
1239 
1240 // Effects
1241 
1243 {
1244  return mEffectFamily;
1245 }
1246 
1248 {
1249  return mEffectType;
1250 }
1251 
1253 {
1254  return mEffectInteractive;
1255 }
1256 
1258 {
1259  return mEffectDefault;
1260 }
1261 
1263 {
1264  return mEffectLegacy;
1265 }
1266 
1268 {
1269  return mEffectRealtime;
1270 }
1271 
1273 {
1274  return mEffectAutomatable;
1275 }
1276 
1277 void PluginDescriptor::SetEffectFamily(const wxString & family)
1278 {
1279  mEffectFamily = family;
1280 }
1281 
1283 {
1284  mEffectType = type;
1285 }
1286 
1288 {
1289  mEffectInteractive = interactive;
1290 }
1291 
1293 {
1294  mEffectDefault = dflt;
1295 }
1296 
1298 {
1299  mEffectLegacy = legacy;
1300 }
1301 
1303 {
1304  mEffectRealtime = realtime;
1305 }
1306 
1308 {
1309  mEffectAutomatable = automatable;
1310 }
1311 
1312 // Importer
1313 
1315 {
1316  return mImporterIdentifier;
1317 }
1318 
1319 void PluginDescriptor::SetImporterIdentifier(const wxString & identifier)
1320 {
1321  mImporterIdentifier = identifier;
1322 }
1323 
1325  const
1326 {
1327  return mImporterExtensions;
1328 }
1329 
1331 {
1332  mImporterExtensions = std::move( extensions );
1333 }
1334 
1336 //
1337 // PluginManager
1338 //
1340 
1341 // Registry has the list of plug ins
1342 #define REGVERKEY wxString(wxT("/pluginregistryversion"))
1343 #define REGVERCUR wxString(wxT("1.1"))
1344 #define REGROOT wxString(wxT("/pluginregistry/"))
1345 
1346 // Settings has the values of the plug in settings.
1347 #define SETVERKEY wxString(wxT("/pluginsettingsversion"))
1348 #define SETVERCUR wxString(wxT("1.0"))
1349 #define SETROOT wxString(wxT("/pluginsettings/"))
1350 
1351 #define KEY_ID wxT("ID")
1352 #define KEY_PATH wxT("Path")
1353 #define KEY_SYMBOL wxT("Symbol")
1354 #define KEY_NAME wxT("Name")
1355 #define KEY_VENDOR wxT("Vendor")
1356 #define KEY_VERSION wxT("Version")
1357 #define KEY_DESCRIPTION wxT("Description")
1358 #define KEY_LASTUPDATED wxT("LastUpdated")
1359 #define KEY_ENABLED wxT("Enabled")
1360 #define KEY_VALID wxT("Valid")
1361 #define KEY_PROVIDERID wxT("ProviderID")
1362 #define KEY_EFFECTTYPE wxT("EffectType")
1363 #define KEY_EFFECTFAMILY wxT("EffectFamily")
1364 #define KEY_EFFECTDEFAULT wxT("EffectDefault")
1365 #define KEY_EFFECTINTERACTIVE wxT("EffectInteractive")
1366 #define KEY_EFFECTREALTIME wxT("EffectRealtime")
1367 #define KEY_EFFECTAUTOMATABLE wxT("EffectAutomatable")
1368 #define KEY_EFFECTTYPE_NONE wxT("None")
1369 #define KEY_EFFECTTYPE_ANALYZE wxT("Analyze")
1370 #define KEY_EFFECTTYPE_GENERATE wxT("Generate")
1371 #define KEY_EFFECTTYPE_PROCESS wxT("Process")
1372 #define KEY_EFFECTTYPE_TOOL wxT("Tool")
1373 #define KEY_EFFECTTYPE_HIDDEN wxT("Hidden")
1374 #define KEY_IMPORTERIDENT wxT("ImporterIdent")
1375 //#define KEY_IMPORTERFILTER wxT("ImporterFilter")
1376 #define KEY_IMPORTEREXTENSIONS wxT("ImporterExtensions")
1377 
1378 // ============================================================================
1379 //
1380 // PluginManagerInterface implementation
1381 //
1382 // ============================================================================
1383 
1385  ModuleInterface *provider, ComponentInterface *pInterface )
1386 {
1387  EffectDefinitionInterface * pEInterface = dynamic_cast<EffectDefinitionInterface*>(pInterface);
1388  if( pEInterface )
1389  return PluginManager::Get().RegisterPlugin(provider, pEInterface, PluginTypeEffect);
1390  ComponentInterface * pCInterface = dynamic_cast<ComponentInterface*>(pInterface);
1391  if( pCInterface )
1392  return PluginManager::Get().RegisterPlugin(provider, pCInterface);
1393  static wxString empty;
1394  return empty;
1395 }
1396 
1398  ModuleInterface *provider, ComponentInterface *pInterface )
1399 {
1400  ComponentInterface * pCInterface = dynamic_cast<ComponentInterface*>(pInterface);
1401  if( pCInterface )
1402  return PluginManager::Get().RegisterPlugin(provider, pCInterface);
1403  static wxString empty;
1404  return empty;
1405 }
1406 
1408 {
1409  auto pPlugin = GetPlugin( ID );
1410  if ( pPlugin )
1411  return GetPluginEnabledSetting( *pPlugin );
1412  return {};
1413 }
1414 
1416  const PluginDescriptor &desc )
1417 {
1418  switch ( desc.GetPluginType() ) {
1419  case PluginTypeModule: {
1420  // Retrieve optional family symbol that was recorded in
1421  // RegisterPlugin() for the module
1422  auto family = desc.GetEffectFamily();
1423  if ( family.empty() ) // as for built-in effect and command modules
1424  return {};
1425  else
1426  return wxT('/') + family + wxT("/Enable");
1427  }
1428  case PluginTypeEffect:
1429  // do NOT use GetEffectFamily() for this descriptor, but instead,
1430  // delegate to the plugin descriptor of the provider, which may
1431  // be different (may be empty)
1432  return GetPluginEnabledSetting( desc.GetProviderID() );
1433  default:
1434  return {};
1435  }
1436 }
1437 
1439 {
1440  for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
1441  {
1442  if (iter->second.GetPath() == path)
1443  {
1444  return true;
1445  }
1446  }
1447 
1448  return false;
1449 }
1450 
1452 {
1453  PluginDescriptor & plug = CreatePlugin(GetID(module), module, PluginTypeModule);
1455 
1456  plug.SetEnabled(true);
1457  plug.SetValid(true);
1458 
1459  return plug.GetID();
1460 }
1461 
1463 {
1465 
1466  plug.SetProviderID(PluginManager::GetID(provider));
1467 
1468  plug.SetEnabled(true);
1469  plug.SetValid(true);
1470 
1471  return plug.GetID();
1472 }
1473 
1475 {
1476  PluginDescriptor & plug = CreatePlugin(GetID(effect), effect, (PluginType)type);
1477 
1478  plug.SetProviderID(PluginManager::GetID(provider));
1479 
1480  plug.SetEffectType(effect->GetClassification());
1481  plug.SetEffectFamily(effect->GetFamily().Internal());
1482  plug.SetEffectInteractive(effect->IsInteractive());
1483  plug.SetEffectDefault(effect->IsDefault());
1484  plug.SetEffectRealtime(effect->SupportsRealtime());
1485  plug.SetEffectAutomatable(effect->SupportsAutomation());
1486 
1487  plug.SetEnabled(true);
1488  plug.SetValid(true);
1489 
1490  return plug.GetID();
1491 }
1492 
1494 {
1495  PluginDescriptor & plug = CreatePlugin(GetID(importer), importer, PluginTypeImporter);
1496 
1497  plug.SetProviderID(PluginManager::GetID(provider));
1498 
1499  plug.SetImporterIdentifier(importer->GetPluginStringID());
1501 
1502  return plug.GetID();
1503 }
1504 
1505 void PluginManager::FindFilesInPathList(const wxString & pattern,
1506  const FilePaths & pathList,
1507  FilePaths & files,
1508  bool directories)
1509 {
1510 
1511  wxLogNull nolog;
1512 
1513  // Why bother...
1514  if (pattern.empty())
1515  {
1516  return;
1517  }
1518 
1519  // TODO: We REALLY need to figure out the "Audacity" plug-in path(s)
1520 
1521  FilePaths paths;
1522 
1523  // Add the "per-user" plug-ins directory
1524  {
1525  const wxFileName &ff = FileNames::PlugInDir();
1526  paths.push_back(ff.GetFullPath());
1527  }
1528 
1529  // Add the "Audacity" plug-ins directory
1530  wxFileName ff = PlatformCompatibility::GetExecutablePath();
1531 #if defined(__WXMAC__)
1532  // Path ends for example in "Audacity.app/Contents/MacOSX"
1533  //ff.RemoveLastDir();
1534  //ff.RemoveLastDir();
1535  // just remove the MacOSX part.
1536  ff.RemoveLastDir();
1537 #endif
1538  ff.AppendDir(wxT("plug-ins"));
1539  paths.push_back(ff.GetPath());
1540 
1541  // Weed out duplicates
1542  for (const auto &filePath : pathList)
1543  {
1544  ff = filePath;
1545  const wxString path{ ff.GetFullPath() };
1546  if (paths.Index(path, wxFileName::IsCaseSensitive()) == wxNOT_FOUND)
1547  {
1548  paths.push_back(path);
1549  }
1550  }
1551 
1552  // Find all matching files in each path
1553  for (size_t i = 0, cnt = paths.size(); i < cnt; i++)
1554  {
1555  ff = paths[i] + wxFILE_SEP_PATH + pattern;
1556  wxDir::GetAllFiles(ff.GetPath(), &files, ff.GetFullName(), directories ? wxDIR_DEFAULT : wxDIR_FILES);
1557  }
1558 
1559  return;
1560 }
1561 
1563 {
1564  return HasGroup(SharedGroup(ID, group));
1565 }
1566 
1568 {
1569  return GetSubgroups(SharedGroup(ID, group), subgroups);
1570 }
1571 
1572 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval)
1573 {
1574  return GetConfig(SharedKey(ID, group, key), value, defval);
1575 }
1576 
1577 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, int & value, int defval)
1578 {
1579  return GetConfig(SharedKey(ID, group, key), value, defval);
1580 }
1581 
1582 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, bool & value, bool defval)
1583 {
1584  return GetConfig(SharedKey(ID, group, key), value, defval);
1585 }
1586 
1587 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, float & value, float defval)
1588 {
1589  return GetConfig(SharedKey(ID, group, key), value, defval);
1590 }
1591 
1592 bool PluginManager::GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, double & value, double defval)
1593 {
1594  return GetConfig(SharedKey(ID, group, key), value, defval);
1595 }
1596 
1597 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const wxString & value)
1598 {
1599  return SetConfig(SharedKey(ID, group, key), value);
1600 }
1601 
1602 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const int & value)
1603 {
1604  return SetConfig(SharedKey(ID, group, key), value);
1605 }
1606 
1607 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const bool & value)
1608 {
1609  return SetConfig(SharedKey(ID, group, key), value);
1610 }
1611 
1612 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const float & value)
1613 {
1614  return SetConfig(SharedKey(ID, group, key), value);
1615 }
1616 
1617 bool PluginManager::SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const double & value)
1618 {
1619  return SetConfig(SharedKey(ID, group, key), value);
1620 }
1621 
1623 {
1624  bool result = GetSettings()->DeleteGroup(SharedGroup(ID, group));
1625  if (result)
1626  {
1627  GetSettings()->Flush();
1628  }
1629 
1630  return result;
1631 }
1632 
1634 {
1635  bool result = GetSettings()->DeleteEntry(SharedKey(ID, group, key));
1636  if (result)
1637  {
1638  GetSettings()->Flush();
1639  }
1640 
1641  return result;
1642 }
1643 
1645 {
1646  return HasGroup(PrivateGroup(ID, group));
1647 }
1648 
1650 {
1651  return GetSubgroups(PrivateGroup(ID, group), subgroups);
1652 }
1653 
1654 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval)
1655 {
1656  return GetConfig(PrivateKey(ID, group, key), value, defval);
1657 }
1658 
1659 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, int & value, int defval)
1660 {
1661  return GetConfig(PrivateKey(ID, group, key), value, defval);
1662 }
1663 
1664 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, bool & value, bool defval)
1665 {
1666  return GetConfig(PrivateKey(ID, group, key), value, defval);
1667 }
1668 
1669 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, float & value, float defval)
1670 {
1671  return GetConfig(PrivateKey(ID, group, key), value, defval);
1672 }
1673 
1674 bool PluginManager::GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, double & value, double defval)
1675 {
1676  return GetConfig(PrivateKey(ID, group, key), value, defval);
1677 }
1678 
1679 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const wxString & value)
1680 {
1681  return SetConfig(PrivateKey(ID, group, key), value);
1682 }
1683 
1684 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const int & value)
1685 {
1686  return SetConfig(PrivateKey(ID, group, key), value);
1687 }
1688 
1689 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const bool & value)
1690 {
1691  return SetConfig(PrivateKey(ID, group, key), value);
1692 }
1693 
1694 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const float & value)
1695 {
1696  return SetConfig(PrivateKey(ID, group, key), value);
1697 }
1698 
1699 bool PluginManager::SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const double & value)
1700 {
1701  return SetConfig(PrivateKey(ID, group, key), value);
1702 }
1703 
1705 {
1706  bool result = GetSettings()->DeleteGroup(PrivateGroup(ID, group));
1707  if (result)
1708  {
1709  GetSettings()->Flush();
1710  }
1711 
1712  return result;
1713 }
1714 
1716 {
1717  bool result = GetSettings()->DeleteEntry(PrivateKey(ID, group, key));
1718  if (result)
1719  {
1720  GetSettings()->Flush();
1721  }
1722 
1723  return result;
1724 }
1725 
1726 // ============================================================================
1727 //
1728 // PluginManager
1729 //
1730 // ============================================================================
1731 
1732 // The one and only PluginManager
1733 std::unique_ptr<PluginManager> PluginManager::mInstance{};
1734 
1735 // ----------------------------------------------------------------------------
1736 // Creation/Destruction
1737 // ----------------------------------------------------------------------------
1738 
1740 {
1741  mSettings = NULL;
1742 }
1743 
1745 {
1746  // Ensure termination (harmless if already done)
1747  Terminate();
1748 }
1749 
1750 // ----------------------------------------------------------------------------
1751 // PluginManager implementation
1752 // ----------------------------------------------------------------------------
1753 
1754 // ============================================================================
1755 //
1756 // Return reference to singleton
1757 //
1758 // (Thread-safe...no active threading during construction or after destruction)
1759 // ============================================================================
1760 
1762 {
1763  if (!mInstance)
1764  {
1766  }
1767 
1768  return *mInstance;
1769 }
1770 
1772 {
1773  // Always load the registry first
1774  Load();
1775 
1776  // And force load of setting to verify it's accessible
1777  GetSettings();
1778 
1779  // Then look for providers (they may autoregister plugins)
1781 
1782  // And finally check for updates
1783 #ifndef EXPERIMENTAL_EFFECT_MANAGEMENT
1784  CheckForUpdates();
1785 #else
1786  const bool kFast = true;
1787  CheckForUpdates( kFast );
1788 #endif
1789 }
1790 
1792 {
1793  // Get rid of all non-module plugins first
1794  PluginMap::iterator iter = mPlugins.begin();
1795  while (iter != mPlugins.end())
1796  {
1797  PluginDescriptor & plug = iter->second;
1798  if (plug.GetPluginType() == PluginTypeEffect)
1799  {
1800  mPlugins.erase(iter++);
1801  continue;
1802  }
1803 
1804  ++iter;
1805  }
1806 
1807  // Now get rid of the modules
1808  iter = mPlugins.begin();
1809  while (iter != mPlugins.end())
1810  {
1811  mPlugins.erase(iter++);
1812  }
1813 }
1814 
1815 bool PluginManager::DropFile(const wxString &fileName)
1816 {
1817  auto &mm = ModuleManager::Get();
1818  const wxFileName src{ fileName };
1819 
1820  for (const PluginDescriptor *plug = GetFirstPlugin(PluginTypeModule);
1821  plug;
1823  {
1824  auto module = static_cast<ModuleInterface *>
1825  (mm.CreateProviderInstance(plug->GetID(), plug->GetPath()));
1826  if (! module)
1827  continue;
1828 
1829  const auto &ff = module->InstallPath();
1830  const auto &extensions = module->GetFileExtensions();
1831  if ( !ff.empty() &&
1832  extensions.Index(src.GetExt(), false) != wxNOT_FOUND ) {
1833  TranslatableString errMsg;
1834  // Do dry-run test of the file format
1835  unsigned nPlugIns =
1836  module->DiscoverPluginsAtPath(fileName, errMsg, {});
1837  if (nPlugIns) {
1838  // File contents are good for this module, so check no others.
1839  // All branches of this block return true, even in case of
1840  // failure for other reasons, to signal that other drag-and-drop
1841  // actions should not be tried.
1842 
1843  // Find path to copy it
1844  wxFileName dst;
1845  dst.AssignDir( ff );
1846  dst.SetFullName( src.GetFullName() );
1847  if ( dst.Exists() ) {
1848  // Query whether to overwrite
1849  bool overwrite = (wxYES == ::AudacityMessageBox(
1850  XO("Overwrite the plug-in file %s?")
1851  .Format( dst.GetFullPath() ),
1852  XO("Plug-in already exists"),
1853  wxYES_NO ) );
1854  if ( !overwrite )
1855  return true;
1856  }
1857 
1858  // Move the file or subtree
1859  bool copied = false;
1860  auto dstPath = dst.GetFullPath();
1861  if ( src.FileExists() )
1862  // A simple one-file plug-in
1863  copied = FileNames::DoCopyFile(
1864  src.GetFullPath(), dstPath, true );
1865  else {
1866  // A sub-folder
1867  // such as for some VST packages
1868  // Recursive copy needed -- to do
1869  return true;
1870  }
1871 
1872  if (!copied) {
1874  XO("Plug-in file is in use. Failed to overwrite") );
1875  return true;
1876  }
1877 
1878  // Register for real
1879  std::vector<PluginID> ids;
1880  std::vector<wxString> names;
1881  nPlugIns = module->DiscoverPluginsAtPath(dstPath, errMsg,
1882  [&](ModuleInterface *provider, ComponentInterface *ident)
1883  -> const PluginID& {
1884  // Register as by default, but also collecting the PluginIDs
1885  // and names
1887  provider, ident);
1888  ids.push_back(id);
1889  names.push_back( ident->GetSymbol().Translation() );
1890  return id;
1891  });
1892  if ( ! nPlugIns ) {
1893  // Unlikely after the dry run succeeded
1895  XO("Failed to register:\n%s").Format( errMsg ) );
1896  return true;
1897  }
1898 
1899  // Ask whether to enable the plug-ins
1900  if (auto nIds = ids.size()) {
1901  auto message = XPC(
1902  /* i18n-hint A plug-in is an optional added program for a sound
1903  effect, or generator, or analyzer */
1904  "Enable this plug-in?\n",
1905  "Enable these plug-ins?\n",
1906  0,
1907  "plug-ins"
1908  )( nIds );
1909  for (const auto &name : names)
1910  message.Join( Verbatim( name ), wxT("\n") );
1911  bool enable = (wxYES == ::AudacityMessageBox(
1912  message,
1913  XO("Enable new plug-ins"),
1914  wxYES_NO ) );
1915  for (const auto &id : ids)
1916  mPlugins[id].SetEnabled(enable);
1917  // Make changes to enabled status persist:
1918  this->Save();
1919  }
1920 
1921  return true;
1922  }
1923  }
1924  }
1925 
1926  return false;
1927 }
1928 
1930 {
1931  // Create/Open the registry
1932  auto pRegistry = AudacityFileConfig::Create(
1933  {}, {}, FileNames::PluginRegistry());
1934  auto &registry = *pRegistry;
1935 
1936  // If this group doesn't exist then we have something that's not a registry.
1937  // We should probably warn the user, but it's pretty unlikely that this will happen.
1938  if (!registry.HasGroup(REGROOT))
1939  {
1940  // Must start over
1941  registry.DeleteAll();
1942  return;
1943  }
1944 
1945  // Check for a registry version that we can understand
1946  // TODO: Should also check for a registry file that is newer than
1947  // what we can understand.
1948  wxString regver = registry.Read(REGVERKEY);
1949  if (regver < REGVERCUR )
1950  {
1951  // Conversion code here, for when registry version changes.
1952 
1953  // We iterate through the effects, possibly updating their info.
1954  wxString groupName;
1955  long groupIndex;
1956  wxString group = GetPluginTypeString(PluginTypeEffect);
1957  wxString cfgPath = REGROOT + group + wxCONFIG_PATH_SEPARATOR;
1958  wxArrayString groupsToDelete;
1959 
1960  registry.SetPath(cfgPath);
1961  for (bool cont = registry.GetFirstGroup(groupName, groupIndex);
1962  cont;
1963  registry.SetPath(cfgPath),
1964  cont = registry.GetNextGroup(groupName, groupIndex))
1965  {
1966  registry.SetPath(groupName);
1967  wxString effectSymbol = registry.Read(KEY_SYMBOL, "");
1968  wxString effectVersion = registry.Read(KEY_VERSION, "");
1969 
1970 
1971  // For 2.3.0 the plugins we distribute have moved around.
1972  // So we upped the registry version number to 1.1.
1973  // These particular config edits were originally written to fix Bug 1914.
1974  if (regver <= "1.0") {
1975  // Nyquist prompt is a built-in that has moved to the tools menu.
1976  if (effectSymbol == "Nyquist Prompt") {
1977  registry.Write(KEY_EFFECTTYPE, "Tool");
1978  // Old version of SDE was in Analyze menu. Now it is in Tools.
1979  // We don't want both the old and the new.
1980  } else if ((effectSymbol == "Sample Data Export") && (effectVersion == "n/a")) {
1981  groupsToDelete.push_back(cfgPath + groupName);
1982  // Old version of SDI was in Generate menu. Now it is in Tools.
1983  } else if ((effectSymbol == "Sample Data Import") && (effectVersion == "n/a")) {
1984  groupsToDelete.push_back(cfgPath + groupName);
1985  }
1986  }
1987 
1988  }
1989  // Doing the deletion within the search loop risked skipping some items,
1990  // hence the delayed delete.
1991  for (unsigned int i = 0; i < groupsToDelete.size(); i++) {
1992  registry.DeleteGroup(groupsToDelete[i]);
1993  }
1994  registry.SetPath("");
1995  registry.Write(REGVERKEY, REGVERCUR);
1996  // Updates done. Make sure we read the updated data later.
1997  registry.Flush();
1998  }
1999 
2000  // Load all provider plugins first
2001  LoadGroup(&registry, PluginTypeModule);
2002 
2003  // Now the rest
2004  LoadGroup(&registry, PluginTypeEffect);
2005  LoadGroup(&registry, PluginTypeAudacityCommand );
2006  LoadGroup(&registry, PluginTypeExporter);
2007  LoadGroup(&registry, PluginTypeImporter);
2008 
2009  LoadGroup(&registry, PluginTypeStub);
2010  return;
2011 }
2012 
2014 {
2015 #ifdef __WXMAC__
2016  // Bug 1590: On Mac, we should purge the registry of Nyquist plug-ins
2017  // bundled with other versions of Audacity, assuming both versions
2018  // were properly installed in /Applications (or whatever it is called in
2019  // your locale)
2020 
2021  const auto fullExePath = PlatformCompatibility::GetExecutablePath();
2022 
2023  // Strip rightmost path components up to *.app
2024  wxFileName exeFn{ fullExePath };
2025  exeFn.SetEmptyExt();
2026  exeFn.SetName(wxString{});
2027  while(exeFn.GetDirCount() && !exeFn.GetDirs().back().EndsWith(".app"))
2028  exeFn.RemoveLastDir();
2029 
2030  const auto goodPath = exeFn.GetPath();
2031 
2032  if(exeFn.GetDirCount())
2033  exeFn.RemoveLastDir();
2034  const auto possiblyBadPath = exeFn.GetPath();
2035 
2036  auto AcceptPath = [&](const wxString &path) {
2037  if (!path.StartsWith(possiblyBadPath))
2038  // Assume it's not under /Applications
2039  return true;
2040  if (path.StartsWith(goodPath))
2041  // It's bundled with this executable
2042  return true;
2043  return false;
2044  };
2045 #else
2046  auto AcceptPath = [](const wxString&){ return true; };
2047 #endif
2048 
2049  wxString strVal;
2050  bool boolVal;
2051  wxString groupName;
2052  long groupIndex;
2053  wxString group = GetPluginTypeString(type);
2054  wxString cfgPath = REGROOT + group + wxCONFIG_PATH_SEPARATOR;
2055 
2056  pRegistry->SetPath(cfgPath);
2057  for (bool cont = pRegistry->GetFirstGroup(groupName, groupIndex);
2058  cont;
2059  pRegistry->SetPath(cfgPath),
2060  cont = pRegistry->GetNextGroup(groupName, groupIndex))
2061  {
2062  PluginDescriptor plug;
2063 
2064  pRegistry->SetPath(groupName);
2065 
2066  groupName = ConvertID(groupName);
2067 
2068  // Bypass group if the ID is already in use
2069  if (mPlugins.find(groupName) != mPlugins.end())
2070  {
2071  pRegistry->SetPath(wxT(".."));
2072 
2073  continue;
2074  }
2075 
2076  // Set the ID and type
2077  plug.SetID(groupName);
2078  plug.SetPluginType(type);
2079 
2080  // Get the provider ID and bypass group if not found
2081  if (!pRegistry->Read(KEY_PROVIDERID, &strVal, wxEmptyString))
2082  {
2083  // Bypass group if the provider isn't valid
2084  if (!strVal.empty() && mPlugins.find(strVal) == mPlugins.end())
2085  {
2086  continue;
2087  }
2088  }
2089  plug.SetProviderID(PluginID(strVal));
2090 
2091  // Get the path (optional)
2092  pRegistry->Read(KEY_PATH, &strVal, wxEmptyString);
2093  if (!AcceptPath(strVal))
2094  // Ignore the obsolete path in the config file, during session,
2095  // but don't remove it from the file. Maybe you really want to
2096  // switch back to the other version of Audacity and lose nothing.
2097  continue;
2098  plug.SetPath(strVal);
2099 
2100  /*
2101  // PRL: Ignore names written in configs before 2.3.0!
2102  // use Internal string only! Let the present version of Audacity map
2103  // that to a user-visible string.
2104  // Get the name and bypass group if not found
2105  if (!pRegistry->Read(KEY_NAME, &strVal))
2106  {
2107  continue;
2108  }
2109  plug.SetName(strVal);
2110  */
2111 
2112  // Get the symbol...Audacity 2.3.0 or later requires it
2113  // bypass group if not found
2114  // Note, KEY_SYMBOL started getting written to config files in 2.1.0.
2115  // KEY_NAME (now ignored) was written before that, but only for VST
2116  // effects.
2117  if (!pRegistry->Read(KEY_SYMBOL, &strVal))
2118  continue;
2119  plug.SetSymbol(strVal);
2120 
2121  // Get the version and bypass group if not found
2122  if (!pRegistry->Read(KEY_VERSION, &strVal))
2123  {
2124  continue;
2125  }
2126  plug.SetVersion(strVal);
2127 
2128  // Get the vendor and bypass group if not found
2129  if (!pRegistry->Read(KEY_VENDOR, &strVal))
2130  {
2131  continue;
2132  }
2133  plug.SetVendor( strVal );
2134 
2135 #if 0
2136  // This was done before version 2.2.2, but the value was not really used
2137  // But absence of a value will cause early versions to skip the group
2138  // Therefore we still write a blank to keep pluginregistry.cfg
2139  // backwards-compatible
2140 
2141  // Get the description and bypass group if not found
2142  if (!pRegistry->Read(KEY_DESCRIPTION, &strVal))
2143  {
2144  continue;
2145  }
2146 #endif
2147 
2148  // Is it enabled...default to no if not found
2149  pRegistry->Read(KEY_ENABLED, &boolVal, false);
2150  plug.SetEnabled(boolVal);
2151 
2152  // Is it valid...default to no if not found
2153  pRegistry->Read(KEY_VALID, &boolVal, false);
2154  plug.SetValid(boolVal);
2155 
2156  switch (type)
2157  {
2158  case PluginTypeModule:
2159  {
2160  // Nothing to do here yet
2161  }
2162  break;
2163 
2164  case PluginTypeEffect:
2165  {
2166  // Get the effect type and bypass group if not found
2167  if (!pRegistry->Read(KEY_EFFECTTYPE, &strVal))
2168  continue;
2169 
2170  if (strVal == KEY_EFFECTTYPE_NONE)
2172  else if (strVal == KEY_EFFECTTYPE_ANALYZE)
2174  else if (strVal == KEY_EFFECTTYPE_GENERATE)
2176  else if (strVal == KEY_EFFECTTYPE_PROCESS)
2178  else if (strVal == KEY_EFFECTTYPE_TOOL)
2180  else if (strVal == KEY_EFFECTTYPE_HIDDEN)
2182  else
2183  continue;
2184 
2185  // Get the effect family and bypass group if not found
2186  if (!pRegistry->Read(KEY_EFFECTFAMILY, &strVal))
2187  {
2188  continue;
2189  }
2190  plug.SetEffectFamily(strVal);
2191 
2192  // Is it a default (above the line) effect and bypass group if not found
2193  if (!pRegistry->Read(KEY_EFFECTDEFAULT, &boolVal))
2194  {
2195  continue;
2196  }
2197  plug.SetEffectDefault(boolVal);
2198 
2199  // Is it an interactive effect and bypass group if not found
2200  if (!pRegistry->Read(KEY_EFFECTINTERACTIVE, &boolVal))
2201  {
2202  continue;
2203  }
2204  plug.SetEffectInteractive(boolVal);
2205 
2206  // Is it a realtime capable effect and bypass group if not found
2207  if (!pRegistry->Read(KEY_EFFECTREALTIME, &boolVal))
2208  {
2209  continue;
2210  }
2211  plug.SetEffectRealtime(boolVal);
2212 
2213  // Does the effect support automation...bypass group if not found
2214  if (!pRegistry->Read(KEY_EFFECTAUTOMATABLE, &boolVal))
2215  {
2216  continue;
2217  }
2218  plug.SetEffectAutomatable(boolVal);
2219  }
2220  break;
2221 
2222  case PluginTypeImporter:
2223  {
2224  // Get the importer identifier and bypass group if not found
2225  if (!pRegistry->Read(KEY_IMPORTERIDENT, &strVal))
2226  {
2227  continue;
2228  }
2229  plug.SetImporterIdentifier(strVal);
2230 
2231  // Get the importer extensions and bypass group if not found
2232  if (!pRegistry->Read(KEY_IMPORTEREXTENSIONS, &strVal))
2233  {
2234  continue;
2235  }
2236  FileExtensions extensions;
2237  wxStringTokenizer tkr(strVal, wxT(":"));
2238  while (tkr.HasMoreTokens())
2239  {
2240  extensions.push_back(tkr.GetNextToken());
2241  }
2242  plug.SetImporterExtensions(extensions);
2243  }
2244  break;
2245 
2246  case PluginTypeStub:
2247  {
2248  // Nothing additional for stubs
2249  }
2250  break;
2251 
2252  // Not used by 2.1.1 or greater and should be removed after a few releases past 2.1.0.
2253  case PluginTypeNone:
2254  {
2255  // Used for stub groups
2256  }
2257  break;
2258 
2259  default:
2260  {
2261  continue;
2262  }
2263  }
2264 
2265  // Everything checked out...accept the plugin
2266  mPlugins[groupName] = plug;
2267  }
2268 
2269  return;
2270 }
2271 
2273 {
2274  // Create/Open the registry
2275  auto pRegistry = AudacityFileConfig::Create(
2276  {}, {}, FileNames::PluginRegistry());
2277  auto &registry = *pRegistry;
2278 
2279  // Clear it out
2280  registry.DeleteAll();
2281 
2282  // Write the version string
2283  registry.Write(REGVERKEY, REGVERCUR);
2284 
2285  // Save the individual groups
2286  SaveGroup(&registry, PluginTypeEffect);
2287  SaveGroup(&registry, PluginTypeExporter);
2289  SaveGroup(&registry, PluginTypeImporter);
2290  SaveGroup(&registry, PluginTypeStub);
2291 
2292  // Not used by 2.1.1 or greater, but must save to allow users to switch between 2.1.0
2293  // and 2.1.1+. This should be removed after a few releases past 2.1.0.
2294  //SaveGroup(&registry, PluginTypeNone);
2295 
2296  // And now the providers
2297  SaveGroup(&registry, PluginTypeModule);
2298 
2299  // Just to be safe
2300  registry.Flush();
2301 }
2302 
2304 {
2305  wxString group = GetPluginTypeString(type);
2306  for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
2307  {
2308  PluginDescriptor & plug = iter->second;
2309 
2310  if (plug.GetPluginType() != type)
2311  {
2312  continue;
2313  }
2314 
2315  pRegistry->SetPath(REGROOT + group + wxCONFIG_PATH_SEPARATOR + ConvertID(plug.GetID()));
2316 
2317  pRegistry->Write(KEY_PATH, plug.GetPath());
2318  pRegistry->Write(KEY_SYMBOL, plug.GetSymbol().Internal());
2319 
2320  // PRL: Writing KEY_NAME which is no longer read, but older Audacity
2321  // versions expect to find it.
2322  pRegistry->Write(KEY_NAME, plug.GetSymbol().Msgid().MSGID());
2323 
2324  pRegistry->Write(KEY_VERSION, plug.GetUntranslatedVersion());
2325  pRegistry->Write(KEY_VENDOR, plug.GetVendor());
2326  // Write a blank -- see comments in LoadGroup:
2327  pRegistry->Write(KEY_DESCRIPTION, wxString{});
2328  pRegistry->Write(KEY_PROVIDERID, plug.GetProviderID());
2329  pRegistry->Write(KEY_ENABLED, plug.IsEnabled());
2330  pRegistry->Write(KEY_VALID, plug.IsValid());
2331 
2332  switch (type)
2333  {
2334  case PluginTypeModule:
2335  break;
2336 
2337  case PluginTypeEffect:
2338  {
2339  EffectType etype = plug.GetEffectType();
2340  wxString stype;
2341  if (etype == EffectTypeNone)
2342  stype = KEY_EFFECTTYPE_NONE;
2343  else if (etype == EffectTypeAnalyze)
2344  stype = KEY_EFFECTTYPE_ANALYZE;
2345  else if (etype == EffectTypeGenerate)
2346  stype = KEY_EFFECTTYPE_GENERATE;
2347  else if (etype == EffectTypeProcess)
2348  stype = KEY_EFFECTTYPE_PROCESS;
2349  else if (etype == EffectTypeTool)
2350  stype = KEY_EFFECTTYPE_TOOL;
2351  else if (etype == EffectTypeHidden)
2352  stype = KEY_EFFECTTYPE_HIDDEN;
2353 
2354  pRegistry->Write(KEY_EFFECTTYPE, stype);
2355  pRegistry->Write(KEY_EFFECTFAMILY, plug.GetEffectFamily());
2356  pRegistry->Write(KEY_EFFECTDEFAULT, plug.IsEffectDefault());
2357  pRegistry->Write(KEY_EFFECTINTERACTIVE, plug.IsEffectInteractive());
2358  pRegistry->Write(KEY_EFFECTREALTIME, plug.IsEffectRealtime());
2359  pRegistry->Write(KEY_EFFECTAUTOMATABLE, plug.IsEffectAutomatable());
2360  }
2361  break;
2362 
2363  case PluginTypeImporter:
2364  {
2365  pRegistry->Write(KEY_IMPORTERIDENT, plug.GetImporterIdentifier());
2366  const auto & extensions = plug.GetImporterExtensions();
2367  wxString strExt;
2368  for (size_t i = 0, cnt = extensions.size(); i < cnt; i++)
2369  {
2370  strExt += extensions[i] + wxT(":");
2371  }
2372  strExt.RemoveLast(1);
2373  pRegistry->Write(KEY_IMPORTEREXTENSIONS, strExt);
2374  }
2375  break;
2376 
2377  default:
2378  break;
2379  }
2380  }
2381 
2382  return;
2383 }
2384 
2385 // If bFast is true, do not do a full check. Just check the ones
2386 // that are quick to check. Currently (Feb 2017) just Nyquist
2387 // and built-ins.
2389 {
2390  // Get ModuleManager reference
2392 
2393  wxArrayString pathIndex;
2394  for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
2395  {
2396  PluginDescriptor & plug = iter->second;
2397 
2398  // Bypass 2.1.0 placeholders...remove this after a few releases past 2.1.0
2399  if (plug.GetPluginType() == PluginTypeNone)
2400  {
2401  continue;
2402  }
2403 
2404  pathIndex.push_back(plug.GetPath().BeforeFirst(wxT(';')));
2405  }
2406 
2407  // Check all known plugins to ensure they are still valid and scan for NEW ones.
2408  //
2409  // All NEW plugins get a stub entry created that will remain in place until the
2410  // user enables or disables the plugin.
2411  //
2412  // Because we use the plugins "path" as returned by the providers, we can actually
2413  // have multiple providers report the same path since, at this point, they only
2414  // know that the path might possibly be one supported by the provider.
2415  //
2416  // When the user enables the plugin, each provider that reported it will be asked
2417  // to register the plugin.
2418  for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
2419  {
2420  PluginDescriptor & plug = iter->second;
2421  const PluginID & plugID = plug.GetID();
2422  const wxString & plugPath = plug.GetPath();
2423  PluginType plugType = plug.GetPluginType();
2424 
2425  // Bypass 2.1.0 placeholders...remove this after a few releases past 2.1.0
2426  if (plugType == PluginTypeNone)
2427  {
2428  continue;
2429  }
2430 
2431  if ( plugType == PluginTypeModule )
2432  {
2433  if( bFast )
2434  {
2435  // Skip modules, when doing a fast refresh/check.
2436  }
2437  else if (!mm.IsProviderValid(plugID, plugPath))
2438  {
2439  plug.SetEnabled(false);
2440  plug.SetValid(false);
2441  }
2442  else
2443  {
2444  // Collect plugin paths
2445  auto paths = mm.FindPluginsForProvider(plugID, plugPath);
2446  for (size_t i = 0, cnt = paths.size(); i < cnt; i++)
2447  {
2448  wxString path = paths[i].BeforeFirst(wxT(';'));;
2449  if ( ! make_iterator_range( pathIndex ).contains( path ) )
2450  {
2451  PluginID ID = plugID + wxT("_") + path;
2452  PluginDescriptor & plug2 = mPlugins[ID]; // This will create a NEW descriptor
2454  plug2.SetID(ID);
2455  plug2.SetProviderID(plugID);
2456  plug2.SetPath(path);
2457  plug2.SetEnabled(false);
2458  plug2.SetValid(false);
2459  }
2460  }
2461  }
2462  }
2463  else if (plugType != PluginTypeNone && plugType != PluginTypeStub)
2464  {
2465  plug.SetValid(mm.IsPluginValid(plug.GetProviderID(), plugPath, bFast));
2466  if (!plug.IsValid())
2467  {
2468  plug.SetEnabled(false);
2469  }
2470  }
2471  }
2472 
2473  Save();
2474 
2475  return;
2476 }
2477 
2478 bool PluginManager::ShowManager(wxWindow *parent, EffectType type)
2479 {
2480  CheckForUpdates();
2481 
2482  PluginRegistrationDialog dlg(parent, type);
2483  return dlg.ShowModal() == wxID_OK;
2484 }
2485 
2486 // Here solely for the purpose of Nyquist Workbench until
2487 // a better solution is devised.
2489 {
2490  PluginDescriptor & plug = CreatePlugin(GetID(effect), effect, type);
2491 
2492  plug.SetEffectType(effect->GetType());
2493  plug.SetEffectFamily(effect->GetFamily().Internal());
2494  plug.SetEffectInteractive(effect->IsInteractive());
2495  plug.SetEffectDefault(effect->IsDefault());
2496  plug.SetEffectRealtime(effect->SupportsRealtime());
2497  plug.SetEffectAutomatable(effect->SupportsAutomation());
2498 
2499  plug.SetInstance(effect);
2500  plug.SetEffectLegacy(true);
2501  plug.SetEnabled(true);
2502  plug.SetValid(true);
2503 
2504  return plug.GetID();
2505 }
2506 
2507 // Here solely for the purpose of Nyquist Workbench until
2508 // a better solution is devised.
2510 {
2511  if (mPlugins.find(ID) == mPlugins.end())
2512  {
2513  return;
2514  }
2515 
2516  mPlugins.erase(ID);
2517 }
2518 
2520 {
2521  int num = 0;
2522 
2523  for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
2524  {
2525  if (iter->second.GetPluginType() == type)
2526  {
2527  num++;
2528  }
2529  }
2530 
2531  return num;
2532 }
2533 
2535 {
2536  if (mPlugins.find(ID) == mPlugins.end())
2537  {
2538  return NULL;
2539  }
2540 
2541  return &mPlugins[ID];
2542 }
2543 
2545 {
2546  for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); ++mPluginsIter)
2547  {
2548  PluginDescriptor & plug = mPluginsIter->second;
2549  PluginType plugType = plug.GetPluginType();
2550  if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0))
2551  {
2552  bool familyEnabled = true;
2553  if( (plugType & PluginTypeEffect) != 0) {
2554  // This preference may be written by EffectsPrefs
2555  auto setting = GetPluginEnabledSetting( plug );
2556  familyEnabled = setting.empty()
2557  ? true
2558  : gPrefs->Read( setting, true );
2559  }
2560  if (familyEnabled)
2561  return &mPluginsIter->second;
2562  }
2563  }
2564 
2565  return NULL;
2566 }
2567 
2569 {
2570  while (++mPluginsIter != mPlugins.end())
2571  {
2572  PluginDescriptor & plug = mPluginsIter->second;
2573  PluginType plugType = plug.GetPluginType();
2574  if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0))
2575  {
2576  bool familyEnabled = true;
2577  if( (plugType & PluginTypeEffect) != 0) {
2578  // This preference may be written by EffectsPrefs
2579  auto setting = GetPluginEnabledSetting( plug );
2580  familyEnabled = setting.empty()
2581  ? true
2582  : gPrefs->Read( setting, true );
2583  }
2584  if (familyEnabled)
2585  return &mPluginsIter->second;
2586  }
2587  }
2588 
2589  return NULL;
2590 }
2591 
2593 {
2594  for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); ++mPluginsIter)
2595  {
2596  PluginDescriptor & plug = mPluginsIter->second;
2597 
2598  bool familyEnabled;
2599  // This preference may be written by EffectsPrefs
2600  auto setting = GetPluginEnabledSetting( plug );
2601  familyEnabled = setting.empty()
2602  ? true
2603  : gPrefs->Read( setting, true );
2604  if (plug.IsValid() && plug.IsEnabled() && plug.GetEffectType() == type && familyEnabled)
2605  {
2606  return &plug;
2607  }
2608  }
2609 
2610  return NULL;
2611 }
2612 
2614 {
2615  while (++mPluginsIter != mPlugins.end())
2616  {
2617  PluginDescriptor & plug = mPluginsIter->second;
2618  bool familyEnabled;
2619  // This preference may be written by EffectsPrefs
2620  auto setting = GetPluginEnabledSetting( plug );
2621  familyEnabled = setting.empty()
2622  ? true
2623  : gPrefs->Read( setting, true );
2624  if (plug.IsValid() && plug.IsEnabled() && plug.GetEffectType() == type && familyEnabled)
2625  {
2626  return &plug;
2627  }
2628  }
2629 
2630  return NULL;
2631 }
2632 
2634 {
2635  if (mPlugins.find(ID) == mPlugins.end())
2636  {
2637  return false;
2638  }
2639 
2640  return mPlugins[ID].IsEnabled();
2641 }
2642 
2643 void PluginManager::EnablePlugin(const PluginID & ID, bool enable)
2644 {
2645  if (mPlugins.find(ID) == mPlugins.end())
2646  {
2647  return;
2648  }
2649 
2650  return mPlugins[ID].SetEnabled(enable);
2651 }
2652 
2654 {
2655  if (mPlugins.find(ID) == mPlugins.end())
2656  {
2657  static ComponentInterfaceSymbol empty;
2658  return empty;
2659  }
2660 
2661  return mPlugins[ID].GetSymbol();
2662 }
2663 
2665 {
2666  if (mPlugins.find(ID) == mPlugins.end())
2667  {
2668  return NULL;
2669  }
2670 
2671  PluginDescriptor & plug = mPlugins[ID];
2672 
2673  // If not dealing with legacy effects, make sure the provider is loaded
2674  if (!plug.IsEffectLegacy())
2675  {
2676  const PluginID & prov = plug.GetProviderID();
2677  if (mPlugins.find(prov) == mPlugins.end())
2678  {
2679  return NULL;
2680  }
2681  mPlugins[prov].GetInstance();
2682  }
2683 
2684  return plug.GetInstance();
2685 }
2686 
2688 {
2689  return wxString::Format(wxT("%s_%s_%s_%s_%s"),
2691  wxEmptyString,
2692  module->GetVendor().Internal(),
2693  module->GetSymbol().Internal(),
2694  module->GetPath());
2695 }
2696 
2698 {
2699  return wxString::Format(wxT("%s_%s_%s_%s_%s"),
2701  wxEmptyString,
2702  command->GetVendor().Internal(),
2703  command->GetSymbol().Internal(),
2704  command->GetPath());
2705 }
2706 
2708 {
2709  return wxString::Format(wxT("%s_%s_%s_%s_%s"),
2711  effect->GetFamily().Internal(),
2712  effect->GetVendor().Internal(),
2713  effect->GetSymbol().Internal(),
2714  effect->GetPath());
2715 }
2716 
2718 {
2719  return wxString::Format(wxT("%s_%s_%s_%s_%s"),
2721  wxEmptyString,
2722  importer->GetVendor().Internal(),
2723  importer->GetSymbol().Internal(),
2724  importer->GetPath());
2725 }
2726 
2727 // This string persists in configuration files
2728 // So config compatibility will break if it is changed across Audacity versions
2730 {
2731  wxString str;
2732 
2733  switch (type)
2734  {
2735  default:
2736  case PluginTypeNone:
2737  str = wxT("Placeholder");
2738  break;
2739  case PluginTypeStub:
2740  str = wxT("Stub");
2741  break;
2742  case PluginTypeEffect:
2743  str = wxT("Effect");
2744  break;
2746  str = wxT("Generic");
2747  break;
2748  case PluginTypeExporter:
2749  str = wxT("Exporter");
2750  break;
2751  case PluginTypeImporter:
2752  str = wxT("Importer");
2753  break;
2754  case PluginTypeModule:
2755  str = wxT("Module");
2756  break;
2757  }
2758 
2759  return str;
2760 }
2761 
2763  ComponentInterface *ident,
2764  PluginType type)
2765 {
2766  // This will either create a NEW entry or replace an existing entry
2767  PluginDescriptor & plug = mPlugins[id];
2768 
2769  plug.SetPluginType(type);
2770 
2771  plug.SetID(id);
2772  plug.SetPath(ident->GetPath());
2773  plug.SetSymbol(ident->GetSymbol());
2774  plug.SetVendor(ident->GetVendor().Internal());
2775  plug.SetVersion(ident->GetVersion());
2776 
2777  return plug;
2778 }
2779 
2781 {
2782  if (!mSettings)
2783  {
2784  mSettings =
2786 
2787  // Check for a settings version that we can understand
2788  if (mSettings->HasEntry(SETVERKEY))
2789  {
2790  wxString setver = mSettings->Read(SETVERKEY, SETVERKEY);
2791  if (setver < SETVERCUR )
2792  {
2793  // This is where we'd put in conversion code when the
2794  // settings version changes.
2795  //
2796  // Should also check for a settings file that is newer than
2797  // what we can understand.
2798  }
2799  }
2800  else
2801  {
2802  // Make sure is has a version string
2803  mSettings->Write(SETVERKEY, SETVERCUR);
2804  mSettings->Flush();
2805  }
2806  }
2807 
2808  return mSettings.get();
2809 }
2810 
2812 {
2813  auto settings = GetSettings();
2814 
2815  bool res = settings->HasGroup(group);
2816  if (res)
2817  {
2818  // The group exists, but empty groups aren't considered valid
2819  wxString oldPath = settings->GetPath();
2820  settings->SetPath(group);
2821  res = settings->GetNumberOfEntries() || settings->GetNumberOfGroups();
2822  settings->SetPath(oldPath);
2823  }
2824 
2825  return res;
2826 }
2827 
2829 {
2830  if (group.empty() || !HasGroup(group))
2831  {
2832  return false;
2833  }
2834 
2835  wxString path = GetSettings()->GetPath();
2836  GetSettings()->SetPath(group);
2837 
2838  wxString name;
2839  long index = 0;
2840  if (GetSettings()->GetFirstGroup(name, index))
2841  {
2842  do
2843  {
2844  subgroups.push_back(name);
2845  } while (GetSettings()->GetNextGroup(name, index));
2846  }
2847 
2848  GetSettings()->SetPath(path);
2849 
2850  return true;
2851 }
2852 
2853 bool PluginManager::GetConfig(const RegistryPath & key, int & value, int defval)
2854 {
2855  bool result = false;
2856 
2857  if (!key.empty())
2858  {
2859  result = GetSettings()->Read(key, &value, defval);
2860  }
2861 
2862  return result;
2863 }
2864 
2865 bool PluginManager::GetConfig(const RegistryPath & key, wxString & value, const wxString & defval)
2866 {
2867  bool result = false;
2868 
2869  if (!key.empty())
2870  {
2871  wxString wxval;
2872 
2873  result = GetSettings()->Read(key, &wxval, defval);
2874 
2875  value = wxval;
2876  }
2877 
2878  return result;
2879 }
2880 
2881 bool PluginManager::GetConfig(const RegistryPath & key, bool & value, bool defval)
2882 {
2883  bool result = false;
2884 
2885  if (!key.empty())
2886  {
2887  result = GetSettings()->Read(key, &value, defval);
2888  }
2889 
2890  return result;
2891 }
2892 
2893 bool PluginManager::GetConfig(const RegistryPath & key, float & value, float defval)
2894 {
2895  bool result = false;
2896 
2897  if (!key.empty())
2898  {
2899  double dval = 0.0;
2900 
2901  result = GetSettings()->Read(key, &dval, (double) defval);
2902 
2903  value = (float) dval;
2904  }
2905 
2906  return result;
2907 }
2908 
2909 bool PluginManager::GetConfig(const RegistryPath & key, double & value, double defval)
2910 {
2911  bool result = false;
2912 
2913  if (!key.empty())
2914  {
2915  result = GetSettings()->Read(key, &value, defval);
2916  }
2917 
2918  return result;
2919 }
2920 
2921 bool PluginManager::SetConfig(const RegistryPath & key, const wxString & value)
2922 {
2923  bool result = false;
2924 
2925  if (!key.empty())
2926  {
2927  wxString wxval = value;
2928  result = GetSettings()->Write(key, wxval);
2929  if (result)
2930  {
2931  result = GetSettings()->Flush();
2932  }
2933  }
2934 
2935  return result;
2936 }
2937 
2938 bool PluginManager::SetConfig(const RegistryPath & key, const int & value)
2939 {
2940  bool result = false;
2941 
2942  if (!key.empty())
2943  {
2944  result = GetSettings()->Write(key, value);
2945  if (result)
2946  {
2947  result = GetSettings()->Flush();
2948  }
2949  }
2950 
2951  return result;
2952 }
2953 
2954 bool PluginManager::SetConfig(const RegistryPath & key, const bool & value)
2955 {
2956  bool result = false;
2957 
2958  if (!key.empty())
2959  {
2960  result = GetSettings()->Write(key, value);
2961  if (result)
2962  {
2963  result = GetSettings()->Flush();
2964  }
2965  }
2966 
2967  return result;
2968 }
2969 
2970 bool PluginManager::SetConfig(const RegistryPath & key, const float & value)
2971 {
2972  bool result = false;
2973 
2974  if (!key.empty())
2975  {
2976  result = GetSettings()->Write(key, value);
2977  if (result)
2978  {
2979  result = GetSettings()->Flush();
2980  }
2981  }
2982 
2983  return result;
2984 }
2985 
2986 bool PluginManager::SetConfig(const RegistryPath & key, const double & value)
2987 {
2988  bool result = false;
2989 
2990  if (!key.empty())
2991  {
2992  result = GetSettings()->Write(key, value);
2993  if (result)
2994  {
2995  result = GetSettings()->Flush();
2996  }
2997  }
2998 
2999  return result;
3000 }
3001 
3002 /* Return value is a key for lookup in a config file */
3004 {
3005  // All the strings reported by PluginDescriptor and used in this function
3006  // persist in the plugin settings configuration file, so they should not
3007  // be changed across Audacity versions, or else compatibility of the
3008  // configuration files will break.
3009 
3010  if (mPlugins.find(ID) == mPlugins.end())
3011  {
3012  return wxEmptyString;
3013  }
3014 
3015  const PluginDescriptor & plug = mPlugins[ID];
3016 
3017  wxString id = GetPluginTypeString(plug.GetPluginType()) +
3018  wxT("_") +
3019  plug.GetEffectFamily() + // is empty for non-Effects
3020  wxT("_") +
3021  plug.GetVendor() +
3022  wxT("_") +
3023  (shared ? wxT("") : plug.GetSymbol().Internal());
3024 
3025  return SETROOT +
3026  ConvertID(id) +
3027  wxCONFIG_PATH_SEPARATOR +
3028  (shared ? wxT("shared") : wxT("private")) +
3029  wxCONFIG_PATH_SEPARATOR;
3030 }
3031 
3032 /* Return value is a key for lookup in a config file */
3034 {
3035  wxString path = SettingsPath(ID, true);
3036 
3037  wxFileName ff(group);
3038  if (!ff.GetName().empty())
3039  {
3040  path += ff.GetFullPath(wxPATH_UNIX) + wxCONFIG_PATH_SEPARATOR;
3041  }
3042 
3043  return path;
3044 }
3045 
3046 /* Return value is a key for lookup in a config file */
3048 {
3049  auto path = SharedGroup(ID, group);
3050  if (path.empty())
3051  {
3052  return path;
3053  }
3054 
3055  return path + key;
3056 }
3057 
3058 /* Return value is a key for lookup in a config file */
3060 {
3061  auto path = SettingsPath(ID, false);
3062 
3063  wxFileName ff(group);
3064  if (!ff.GetName().empty())
3065  {
3066  path += ff.GetFullPath(wxPATH_UNIX) + wxCONFIG_PATH_SEPARATOR;
3067  }
3068 
3069  return path;
3070 }
3071 
3072 /* Return value is a key for lookup in a config file */
3074 {
3075  auto path = PrivateGroup(ID, group);
3076  if (path.empty())
3077  {
3078  return path;
3079  }
3080 
3081  return path + key;
3082 }
3083 
3084 // Sanitize the ID...not the best solution, but will suffice until this
3085 // is converted to XML. We use base64 encoding to preserve case.
3087 {
3088  if (ID.StartsWith(wxT("base64:")))
3089  {
3090  wxString id = ID.Mid(7);
3091  ArrayOf<char> buf{ id.length() / 4 * 3 };
3092  id = wxString::FromUTF8(buf.get(), b64decode(id, buf.get()));
3093  return id;
3094  }
3095 
3096  const wxCharBuffer & buf = ID.ToUTF8();
3097  return wxT("base64:") + b64encode(buf, strlen(buf));
3098 }
3099 
3101 // Base64 en/decoding
3102 //
3103 // Original routines marked as public domain and found at:
3104 //
3105 // http://en.wikibooks.org/wiki/Algorithm_implementation/Miscellaneous/Base64
3106 //
3108 
3109 // Lookup table for encoding
3110 const static wxChar cset[] = wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
3111 const static char padc = wxT('=');
3112 
3113 wxString PluginManager::b64encode(const void *in, int len)
3114 {
3115  unsigned char *p = (unsigned char *) in;
3116  wxString out;
3117 
3118  unsigned long temp;
3119  for (int i = 0; i < len / 3; i++)
3120  {
3121  temp = (*p++) << 16; //Convert to big endian
3122  temp += (*p++) << 8;
3123  temp += (*p++);
3124  out += cset[(temp & 0x00FC0000) >> 18];
3125  out += cset[(temp & 0x0003F000) >> 12];
3126  out += cset[(temp & 0x00000FC0) >> 6];
3127  out += cset[(temp & 0x0000003F)];
3128  }
3129 
3130  switch (len % 3)
3131  {
3132  case 1:
3133  temp = (*p++) << 16; //Convert to big endian
3134  out += cset[(temp & 0x00FC0000) >> 18];
3135  out += cset[(temp & 0x0003F000) >> 12];
3136  out += padc;
3137  out += padc;
3138  break;
3139 
3140  case 2:
3141  temp = (*p++) << 16; //Convert to big endian
3142  temp += (*p++) << 8;
3143  out += cset[(temp & 0x00FC0000) >> 18];
3144  out += cset[(temp & 0x0003F000) >> 12];
3145  out += cset[(temp & 0x00000FC0) >> 6];
3146  out += padc;
3147  break;
3148  }
3149 
3150  return out;
3151 }
3152 
3153 int PluginManager::b64decode(const wxString &in, void *out)
3154 {
3155  int len = in.length();
3156  unsigned char *p = (unsigned char *) out;
3157 
3158  if (len % 4) //Sanity check
3159  {
3160  return 0;
3161  }
3162 
3163  int padding = 0;
3164  if (len)
3165  {
3166  if (in[len - 1] == padc)
3167  {
3168  padding++;
3169  }
3170 
3171  if (in[len - 2] == padc)
3172  {
3173  padding++;
3174  }
3175  }
3176 
3177  //const char *a = in.mb_str();
3178  //Setup a vector to hold the result
3179  unsigned long temp = 0; //Holds decoded quanta
3180  int i = 0;
3181  while (i < len)
3182  {
3183  for (int quantumPosition = 0; quantumPosition < 4; quantumPosition++)
3184  {
3185  unsigned char c = in[i];
3186  temp <<= 6;
3187 
3188  if (c >= 0x41 && c <= 0x5A)
3189  {
3190  temp |= c - 0x41;
3191  }
3192  else if (c >= 0x61 && c <= 0x7A)
3193  {
3194  temp |= c - 0x47;
3195  }
3196  else if (c >= 0x30 && c <= 0x39)
3197  {
3198  temp |= c + 0x04;
3199  }
3200  else if (c == 0x2B)
3201  {
3202  temp |= 0x3E;
3203  }
3204  else if (c == 0x2F)
3205  {
3206  temp |= 0x3F;
3207  }
3208  else if (c == padc)
3209  {
3210  switch (len - i)
3211  {
3212  case 1: //One pad character
3213  *p++ = (temp >> 16) & 0x000000FF;
3214  *p++ = (temp >> 8) & 0x000000FF;
3215  return p - (unsigned char *) out;
3216  case 2: //Two pad characters
3217  *p++ = (temp >> 10) & 0x000000FF;
3218  return p - (unsigned char *) out;
3219  }
3220  }
3221  i++;
3222  }
3223  *p++ = (temp >> 16) & 0x000000FF;
3224  *p++ = (temp >> 8) & 0x000000FF;
3225  *p++ = temp & 0x000000FF;
3226  }
3227 
3228  return p - (unsigned char *) out;
3229 }
3230 
3231 // This is defined out-of-line here, to keep ComponentInterface free of other
3232 // #include directives.
3234 {
3235  return GetSymbol().Msgid();
3236 }
PluginManager::b64decode
int b64decode(const wxString &in, void *out)
Definition: PluginManager.cpp:3153
EVT_BUTTON
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
RegistryPaths
std::vector< RegistryPath > RegistryPaths
Definition: Types.h:262
PluginDescriptor::mEffectLegacy
bool mEffectLegacy
Definition: PluginManager.h:149
FileConfig::SetPath
virtual void SetPath(const wxString &strPath) wxOVERRIDE
Definition: FileConfig.cpp:101
TranslatableString
Definition: Types.h:290
PluginRegistrationDialog::mType
EffectType mType
Definition: PluginManager.cpp:445
PluginManager::GetInstance
ComponentInterface * GetInstance(const PluginID &ID)
Definition: PluginManager.cpp:2664
PluginDescriptor::mVendor
wxString mVendor
Definition: PluginManager.h:138
PluginRegistrationDialog::Populate
void Populate()
Definition: PluginManager.cpp:502
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:36
FileNames::PluginRegistry
AUDACITY_DLL_API FilePath PluginRegistry()
TranslatableString::empty
bool empty() const
Definition: Types.h:329
PluginManager::RemovePrivateConfigSubgroup
bool RemovePrivateConfigSubgroup(const PluginID &ID, const RegistryPath &group) override
Definition: PluginManager.cpp:1704
PluginRegistrationDialog::SortCompare
static int wxCALLBACK SortCompare(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
Definition: PluginManager.cpp:825
KEY_EFFECTFAMILY
#define KEY_EFFECTFAMILY
Definition: PluginManager.cpp:1363
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1177
PluginManager::Save
void Save()
Definition: PluginManager.cpp:2272
FileNames::DoCopyFile
AUDACITY_DLL_API bool DoCopyFile(const FilePath &file1, const FilePath &file2, bool overwrite=true)
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:59
PluginDescriptor::IsEffectInteractive
bool IsEffectInteractive() const
Definition: PluginManager.cpp:1252
wxFileNameWrapper.h
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:625
PluginManager::GetSharedConfig
bool GetSharedConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key, wxString &value, const wxString &defval=_T("")) override
Definition: PluginManager.cpp:1572
PluginManager::GetPluginTypeString
static wxString GetPluginTypeString(PluginType type)
Definition: PluginManager.cpp:2729
PluginManagerInterface::AudacityCommandRegistrationCallback
static const PluginID & AudacityCommandRegistrationCallback(ModuleInterface *provider, ComponentInterface *ident)
Definition: PluginManager.cpp:1397
PluginDescriptor::mInstance
ComponentInterface * mInstance
Definition: PluginManager.h:130
PluginDescriptor::IsEffectRealtime
bool IsEffectRealtime() const
Definition: PluginManager.cpp:1267
COL_Path
@ COL_Path
Definition: PluginManager.cpp:413
ComponentInterfaceSymbol::Translation
const wxString Translation() const
Definition: ComponentInterface.h:91
PluginManager::mPlugins
PluginMap mPlugins
Definition: PluginManager.h:321
PluginRegistrationDialog::mItems
ItemDataMap mItems
Definition: PluginManager.cpp:449
ComponentInterface::GetSymbol
virtual ComponentInterfaceSymbol GetSymbol()=0
PluginDescriptor::GetEffectFamily
wxString GetEffectFamily() const
Definition: PluginManager.cpp:1242
flag
static std::once_flag flag
Definition: WaveformView.cpp:1113
KEY_EFFECTTYPE_NONE
#define KEY_EFFECTTYPE_NONE
Definition: PluginManager.cpp:1368
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:67
PluginDescriptor::SetPath
void SetPath(const PluginPath &path)
Definition: PluginManager.cpp:1210
PluginManager::PluginManager
PluginManager()
Definition: PluginManager.cpp:1739
PluginManager::SharedKey
RegistryPath SharedKey(const PluginID &ID, const RegistryPath &group, const RegistryPath &key)
Definition: PluginManager.cpp:3047
PluginManager::FindFilesInPathList
void FindFilesInPathList(const wxString &pattern, const FilePaths &pathList, FilePaths &files, bool directories=false) override
Definition: PluginManager.cpp:1505
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: AudacityMessageBox.h:20
PluginDescriptor::GetImporterExtensions
const FileExtensions & GetImporterExtensions() const
Definition: PluginManager.cpp:1324
PluginManager::mPluginsIter
PluginMap::iterator mPluginsIter
Definition: PluginManager.h:322
PluginDescriptor::SetEffectAutomatable
void SetEffectAutomatable(bool automatable)
Definition: PluginManager.cpp:1307
PluginRegistrationDialog::OnChangedVisibility
void OnChangedVisibility(wxCommandEvent &evt)
Definition: PluginManager.cpp:862
EffectInterface.h
PluginManager::GetConfig
bool GetConfig(const RegistryPath &key, wxString &value, const wxString &defval=L"")
Definition: PluginManager.cpp:2865
ModuleManager.h
PluginDescriptor::GetProviderID
const wxString & GetProviderID() const
Definition: PluginManager.cpp:1160
EffectTypeGenerate
@ EffectTypeGenerate
Definition: EffectInterface.h:58
PluginManager::GetSymbol
const ComponentInterfaceSymbol & GetSymbol(const PluginID &ID)
Definition: PluginManager.cpp:2653
PluginType
PluginType
Definition: PluginManager.h:33
cset
static const wxChar cset[]
Definition: PluginManager.cpp:3110
PluginDescriptor::GetPluginType
PluginType GetPluginType() const
Definition: PluginManager.cpp:1150
STATE_Enabled
@ STATE_Enabled
Definition: PluginManager.cpp:375
pdlgHideStopButton
@ pdlgHideStopButton
Definition: ProgressDialog.h:43
KEY_IMPORTEREXTENSIONS
#define KEY_IMPORTEREXTENSIONS
Definition: PluginManager.cpp:1376
ItemData::nameWidth
int nameWidth
Definition: PluginManager.cpp:389
Format
Abstract base class used in importing a file.
KEY_PATH
#define KEY_PATH
Definition: PluginManager.cpp:1352
ShuttleGuiBase::AddRadioButtonToGroup
wxRadioButton * AddRadioButtonToGroup(const TranslatableString &Prompt, int selector=1, int initValue=0)
Definition: ShuttleGui.cpp:567
PluginDescriptor::mVersion
wxString mVersion
Definition: PluginManager.h:137
ModuleInterface.h
EffectTypeNone
@ EffectTypeNone
Definition: EffectInterface.h:56
SETVERKEY
#define SETVERKEY
Definition: PluginManager.cpp:1347
ShuttleGui::AddSpace
wxSizerItem * AddSpace(int width, int height, int prop=0)
Definition: ShuttleGui.cpp:2421
EffectDefinitionInterface::IsInteractive
virtual bool IsInteractive()=0
PluginManager::RegisterPlugin
const PluginID & RegisterPlugin(ModuleInterface *module) override
Definition: PluginManager.cpp:1451
PluginDescriptor::DeleteInstance
void DeleteInstance()
Definition: PluginManager.cpp:1106
PluginDescriptor::mProviderID
wxString mProviderID
Definition: PluginManager.h:139
FileConfig::DeleteEntry
virtual bool DeleteEntry(const wxString &key, bool bDeleteGroupIfEmpty=true) wxOVERRIDE
Definition: FileConfig.cpp:217
XO
#define XO(s)
Definition: Internat.h:32
ProgressResult::Cancelled
@ Cancelled
PluginDescriptor::SetEffectInteractive
void SetEffectInteractive(bool interactive)
Definition: PluginManager.cpp:1287
ModuleManager::RegisterEffectPlugin
bool RegisterEffectPlugin(const PluginID &provider, const PluginPath &path, TranslatableString &errMsg)
Definition: ModuleManager.cpp:548
PluginManager::GetSharedConfigSubgroups
bool GetSharedConfigSubgroups(const PluginID &ID, const RegistryPath &group, RegistryPaths &subgroups) override
Definition: PluginManager.cpp:1567
PluginRegistrationDialog::OnSort
void OnSort(wxListEvent &evt)
Definition: PluginManager.cpp:868
PluginManager::RemoveSharedConfig
bool RemoveSharedConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key) override
Definition: PluginManager.cpp:1633
COL_State
@ COL_State
Definition: PluginManager.cpp:412
ProgressDialog.h
ID_List
@ ID_List
Definition: PluginManager.cpp:402
eCancelButton
@ eCancelButton
Definition: ShuttleGui.h:608
PluginDescriptor::IsEffectAutomatable
bool IsEffectAutomatable() const
Definition: PluginManager.cpp:1272
ModuleInterface::InstallPath
virtual FilePath InstallPath()=0
KEY_IMPORTERIDENT
#define KEY_IMPORTERIDENT
Definition: PluginManager.cpp:1374
EffectDefinitionInterface::SupportsRealtime
virtual bool SupportsRealtime()=0
PluginRegistrationDialog
Definition: PluginManager.cpp:419
ModuleManager::IsPluginValid
bool IsPluginValid(const PluginID &provider, const PluginPath &path, bool bFast)
Definition: ModuleManager.cpp:612
ItemData::plugs
std::vector< PluginDescriptor * > plugs
Definition: PluginManager.cpp:384
FileConfig::GetFirstGroup
virtual bool GetFirstGroup(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:111
EffectDefinitionInterface::SupportsAutomation
virtual bool SupportsAutomation()=0
PluginManager::HasGroup
bool HasGroup(const RegistryPath &group)
Definition: PluginManager.cpp:2811
ID_ShowNew
@ ID_ShowNew
Definition: PluginManager.cpp:401
PluginDescriptor::mEffectDefault
bool mEffectDefault
Definition: PluginManager.h:148
ComponentInterfaceSymbol::Msgid
const TranslatableString & Msgid() const
Definition: ComponentInterface.h:89
PluginManager::HasPrivateConfigGroup
bool HasPrivateConfigGroup(const PluginID &ID, const RegistryPath &group)
Definition: PluginManager.cpp:1644
PluginDescriptor::mPluginType
PluginType mPluginType
Definition: PluginManager.h:132
wxArrayStringEx
Definition: MemoryX.h:663
PluginRegistrationDialog::OnDisable
void OnDisable(wxCommandEvent &evt)
Definition: PluginManager.cpp:953
ModuleManager::DiscoverProviders
bool DiscoverProviders()
Definition: ModuleManager.cpp:404
PluginDescriptor::SetProviderID
void SetProviderID(const PluginID &providerID)
Definition: PluginManager.cpp:1205
PluginTypeImporter
@ PluginTypeImporter
Definition: PluginManager.h:39
PluginManager::RemovePrivateConfig
bool RemovePrivateConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key) override
Definition: PluginManager.cpp:1715
desc
const TranslatableString desc
Definition: ExportPCM.cpp:56
PluginRegistrationDialog::mSortDirection
int mSortDirection
Definition: PluginManager.cpp:452
PluginDescriptor::PluginDescriptor
PluginDescriptor()
Definition: PluginManager.cpp:1086
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterface.h:60
PluginManager::SettingsPath
RegistryPath SettingsPath(const PluginID &ID, bool shared)
Definition: PluginManager.cpp:3003
PluginDescriptor::SetImporterExtensions
void SetImporterExtensions(FileExtensions extensions)
Definition: PluginManager.cpp:1330
ImporterInterface::GetPluginStringID
virtual wxString GetPluginStringID()=0
ShuttleGui::Id
ShuttleGui & Id(int id)
Definition: ShuttleGui.cpp:2248
KEY_VENDOR
#define KEY_VENDOR
Definition: PluginManager.cpp:1355
PluginRegistrationDialog::PluginRegistrationDialog
PluginRegistrationDialog(wxWindow *parent, EffectType type)
Definition: PluginManager.cpp:478
ComponentInterface::GetVendor
virtual VendorSymbol GetVendor()=0
ID_SelectAll
@ ID_SelectAll
Definition: PluginManager.cpp:404
PluginTypeModule
@ PluginTypeModule
Definition: PluginManager.h:40
ItemData::valid
bool valid
Definition: PluginManager.cpp:388
ModuleInterface
Definition: ModuleInterface.h:68
PluginManager::DropFile
bool DropFile(const wxString &fileName)
Definition: PluginManager.cpp:1815
ShuttleGui::Style
ShuttleGui & Style(long iStyle)
Definition: ShuttleGui.h:734
eOkButton
@ eOkButton
Definition: ShuttleGui.h:607
PluginDescriptor::SetSymbol
void SetSymbol(const ComponentInterfaceSymbol &symbol)
Definition: PluginManager.cpp:1215
PluginDescriptor::GetVendor
wxString GetVendor() const
Definition: PluginManager.cpp:1180
PluginManager::~PluginManager
~PluginManager()
Definition: PluginManager.cpp:1744
FileConfig::GetNextGroup
virtual bool GetNextGroup(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:116
KEY_EFFECTINTERACTIVE
#define KEY_EFFECTINTERACTIVE
Definition: PluginManager.cpp:1365
ItemData
Definition: PluginManager.cpp:383
PluginDescriptor::SetValid
void SetValid(bool valid)
Definition: PluginManager.cpp:1235
ID_ClearAll
@ ID_ClearAll
Definition: PluginManager.cpp:403
XXO
#define XXO(s)
Definition: Internat.h:45
ModuleManager::IsProviderValid
bool IsProviderValid(const PluginID &provider, const PluginPath &path)
Definition: ModuleManager.cpp:594
PluginDescriptor::mPath
PluginPath mPath
Definition: PluginManager.h:135
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1170
ModuleManager
Definition: ModuleManager.h:79
ProgressDialog
ProgressDialog Class.
Definition: ProgressDialog.h:56
KEY_NAME
#define KEY_NAME
Definition: PluginManager.cpp:1354
PluginRegistrationDialog::OnEnable
void OnEnable(wxCommandEvent &evt)
Definition: PluginManager.cpp:934
KEY_PROVIDERID
#define KEY_PROVIDERID
Definition: PluginManager.cpp:1361
PluginManager::SharedGroup
RegistryPath SharedGroup(const PluginID &ID, const RegistryPath &group)
Definition: PluginManager.cpp:3033
PluginDescriptor::mEffectInteractive
bool mEffectInteractive
Definition: PluginManager.h:147
PluginDescriptor::IsInstantiated
bool IsInstantiated() const
Definition: PluginManager.cpp:1115
PluginRegistrationDialog::OnListChar
void OnListChar(wxKeyEvent &evt)
Definition: PluginManager.cpp:892
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1160
XPC
#define XPC(sing, plur, n, c)
Definition: Internat.h:101
ComponentInterface::GetPath
virtual PluginPath GetPath()=0
PluginManager.h
PluginManager::GetFirstPluginForEffectType
const PluginDescriptor * GetFirstPluginForEffectType(EffectType type)
Definition: PluginManager.cpp:2592
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1196
PluginRegistrationDialog::OnCancel
void OnCancel(wxCommandEvent &evt)
Definition: PluginManager.cpp:1073
KEY_ENABLED
#define KEY_ENABLED
Definition: PluginManager.cpp:1359
ID_Enable
@ ID_Enable
Definition: PluginManager.cpp:405
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:1679
ModuleManager::Get
static ModuleManager & Get()
Definition: ModuleManager.cpp:394
PluginManager::mSettings
std::unique_ptr< FileConfig > mSettings
Definition: PluginManager.h:316
PluginRegistrationDialog::mEffects
wxListCtrl * mEffects
Definition: PluginManager.cpp:456
PluginDescriptor::GetUntranslatedVersion
wxString GetUntranslatedVersion() const
Definition: PluginManager.cpp:1175
name
const TranslatableString name
Definition: Distortion.cpp:98
SETVERCUR
#define SETVERCUR
Definition: PluginManager.cpp:1348
PluginRegistrationDialog::mFilter
int mFilter
Definition: PluginManager.cpp:446
PluginPath
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Types.h:257
PluginManager::GetPrivateConfigSubgroups
bool GetPrivateConfigSubgroups(const PluginID &ID, const RegistryPath &group, RegistryPaths &subgroups) override
Definition: PluginManager.cpp:1649
EffectTypeTool
@ EffectTypeTool
Definition: EffectInterface.h:61
SETROOT
#define SETROOT
Definition: PluginManager.cpp:1349
AudacityFileConfig.h
ModuleManager::FindPluginsForProvider
PluginPaths FindPluginsForProvider(const PluginID &provider, const PluginPath &path)
Definition: ModuleManager.cpp:532
PluginManager::Initialize
void Initialize()
Definition: PluginManager.cpp:1771
ImporterInterface
Definition: ImporterInterface.h:58
PluginDescriptor::SetImporterIdentifier
void SetImporterIdentifier(const wxString &identifier)
Definition: PluginManager.cpp:1319
WindowAccessible
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
ItemData::pathWidth
int pathWidth
Definition: PluginManager.cpp:390
PluginDescriptor
Definition: PluginManager.h:45
PluginDescriptor::mValid
bool mValid
Definition: PluginManager.h:141
EffectDefinitionInterface::GetType
virtual EffectType GetType()=0
PluginDescriptor::mID
wxString mID
Definition: PluginManager.h:134
FileNames::PluginSettings
AUDACITY_DLL_API FilePath PluginSettings()
ShuttleGuiBase::AddRadioButton
wxRadioButton * AddRadioButton(const TranslatableString &Prompt, int selector=0, int initValue=0)
Definition: ShuttleGui.cpp:561
EffectTypeHidden
@ EffectTypeHidden
Definition: EffectInterface.h:57
PluginManager::UnregisterPlugin
void UnregisterPlugin(const PluginID &ID)
Definition: PluginManager.cpp:2509
PluginRegistrationDialog::DoSort
void DoSort(int col)
Definition: PluginManager.cpp:874
PluginManager::Load
void Load()
Definition: PluginManager.cpp:1929
ShuttleGui.h
PluginDescriptor::SetEffectFamily
void SetEffectFamily(const wxString &family)
Definition: PluginManager.cpp:1277
PluginDescriptor::mSymbol
ComponentInterfaceSymbol mSymbol
Definition: PluginManager.h:136
PluginManager::SaveGroup
void SaveGroup(FileConfig *pRegistry, PluginType type)
Definition: PluginManager.cpp:2303
KEY_EFFECTDEFAULT
#define KEY_EFFECTDEFAULT
Definition: PluginManager.cpp:1364
ModuleManager::CreateInstance
ComponentInterface * CreateInstance(const PluginID &provider, const PluginPath &path)
Definition: ModuleManager.cpp:572
COL_Name
@ COL_Name
Definition: PluginManager.cpp:411
KEY_EFFECTAUTOMATABLE
#define KEY_EFFECTAUTOMATABLE
Definition: PluginManager.cpp:1367
ShuttleGuiBase::AddButton
wxButton * AddButton(const TranslatableString &Text, int PositionFlags=wxALIGN_CENTRE, bool setDefault=false)
Definition: ShuttleGui.cpp:353
EffectDefinitionInterface::GetClassification
virtual EffectType GetClassification()
Definition: EffectInterface.h:81
FileConfig
Definition: FileConfig.h:22
KEY_SYMBOL
#define KEY_SYMBOL
Definition: PluginManager.cpp:1353
FileConfig::DeleteGroup
virtual bool DeleteGroup(const wxString &key) wxOVERRIDE
Definition: FileConfig.cpp:227
id
int id
Definition: WaveTrackControls.cpp:589
ItemData::state
int state
Definition: PluginManager.cpp:387
PluginManager::GetPrivateConfig
bool GetPrivateConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key, wxString &value, const wxString &defval=_T("")) override
Definition: PluginManager.cpp:1654
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
KEY_VERSION
#define KEY_VERSION
Definition: PluginManager.cpp:1356
PluginRegistrationDialog::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S)
Defines the dialog and does data exchange with it.
Definition: PluginManager.cpp:511
PluginDescriptor::GetID
const wxString & GetID() const
Definition: PluginManager.cpp:1155
ShuttleGui::Name
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:670
PluginManager::mInstance
static std::unique_ptr< PluginManager > mInstance
Definition: PluginManager.h:312
PluginManagerInterface::DefaultRegistrationCallback
static const PluginID & DefaultRegistrationCallback(ModuleInterface *provider, ComponentInterface *ident)
Definition: PluginManager.cpp:1384
wxDialogWrapper
Definition: wxPanelWrapper.h:81
PluginDescriptor::mImporterIdentifier
wxString mImporterIdentifier
Definition: PluginManager.h:155
PluginManager::Get
static PluginManager & Get()
Definition: PluginManager.cpp:1761
PluginManager::CreatePlugin
PluginDescriptor & CreatePlugin(const PluginID &id, ComponentInterface *ident, PluginType type)
Definition: PluginManager.cpp:2762
PluginDescriptor::GetEffectType
EffectType GetEffectType() const
Definition: PluginManager.cpp:1247
ModuleManager::DeleteInstance
void DeleteInstance(const PluginID &provider, ComponentInterface *instance)
Definition: ModuleManager.cpp:583
COL_COUNT
@ COL_COUNT
Definition: PluginManager.cpp:415
FileNames::PlugInDir
AUDACITY_DLL_API FilePath PlugInDir()
The user plug-in directory (not a system one)
PluginRegistrationDialog::mSortColumn
int mSortColumn
Definition: PluginManager.cpp:451
ID_ShowAll
@ ID_ShowAll
Definition: PluginManager.cpp:398
PluginManager::EnablePlugin
void EnablePlugin(const PluginID &ID, bool enable)
Definition: PluginManager.cpp:2643
EffectDefinitionInterface
EffectDefinitionInterface is a ComponentInterface that additionally tracks flag-functions for interac...
Definition: EffectInterface.h:74
WindowAccessible.h
PluginManager::CheckForUpdates
void CheckForUpdates(bool bFast=false)
Definition: PluginManager.cpp:2388
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:151
PluginManager::b64encode
wxString b64encode(const void *in, int len)
Definition: PluginManager.cpp:3113
ItemDataMap
std::unordered_map< PluginPath, ItemData > ItemDataMap
Definition: PluginManager.cpp:394
ID_Disable
@ ID_Disable
Definition: PluginManager.cpp:406
PlatformCompatibility.h
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: CommandManager.cpp:196
PluginDescriptor::IsEnabled
bool IsEnabled() const
Definition: PluginManager.cpp:1185
PluginManager
PluginManager maintains a list of all plug ins. That covers modules, effects, generators,...
Definition: PluginManager.h:172
KEY_EFFECTREALTIME
#define KEY_EFFECTREALTIME
Definition: PluginManager.cpp:1366
PluginDescriptor::SetEffectRealtime
void SetEffectRealtime(bool realtime)
Definition: PluginManager.cpp:1302
names
static TranslatableStrings names
Definition: Tags.cpp:743
KEY_EFFECTTYPE_ANALYZE
#define KEY_EFFECTTYPE_ANALYZE
Definition: PluginManager.cpp:1369
PluginDescriptor::GetInstance
ComponentInterface * GetInstance()
Definition: PluginManager.cpp:1120
_
#define _(s)
Definition: Internat.h:76
PluginRegistrationDialog::OnSelectAll
void OnSelectAll(wxCommandEvent &evt)
Definition: PluginManager.cpp:918
PluginManager::GetID
static PluginID GetID(ModuleInterface *module)
Definition: PluginManager.cpp:2687
KEY_EFFECTTYPE
#define KEY_EFFECTTYPE
Definition: PluginManager.cpp:1362
ShuttleGui::ConnectRoot
auto ConnectRoot(wxEventTypeTag< Tag > eventType, void(Handler::*func)(Argument &)) -> typename std::enable_if< std::is_base_of< Argument, Tag >::value, ShuttleGui & >::type
Definition: ShuttleGui.h:706
PluginTypeNone
@ PluginTypeNone
Definition: PluginManager.h:34
REGROOT
#define REGROOT
Definition: PluginManager.cpp:1344
EffectTypeAnalyze
@ EffectTypeAnalyze
Definition: EffectInterface.h:60
PluginDescriptor::mEnabled
bool mEnabled
Definition: PluginManager.h:140
KEY_EFFECTTYPE_GENERATE
#define KEY_EFFECTTYPE_GENERATE
Definition: PluginManager.cpp:1370
PluginDescriptor::GetImporterIdentifier
const wxString & GetImporterIdentifier() const
Definition: PluginManager.cpp:1314
PluginManager::GetPluginCount
int GetPluginCount(PluginType type)
Definition: PluginManager.cpp:2519
FileNames.h
Verbatim
TranslatableString Verbatim(wxString str)
Definition: Types.h:581
PluginDescriptor::mEffectRealtime
bool mEffectRealtime
Definition: PluginManager.h:150
AudacityMessageBox.h
PluginManager::IsPluginEnabled
bool IsPluginEnabled(const PluginID &ID)
Definition: PluginManager.cpp:2633
PluginDescriptor::SetEffectType
void SetEffectType(EffectType type)
Definition: PluginManager.cpp:1282
PluginRegistrationDialog::mStates
wxArrayString mStates
Definition: PluginManager.cpp:448
KEY_DESCRIPTION
#define KEY_DESCRIPTION
Definition: PluginManager.cpp:1357
ModuleInterface::GetOptionalFamilySymbol
virtual EffectFamilySymbol GetOptionalFamilySymbol()=0
PluginDescriptor::GetSymbol
const ComponentInterfaceSymbol & GetSymbol() const
Definition: PluginManager.cpp:1170
ComponentInterfaceSymbol::Internal
const wxString & Internal() const
Definition: ComponentInterface.h:88
PluginDescriptor::IsEffectLegacy
bool IsEffectLegacy() const
Definition: PluginManager.cpp:1262
PluginManager::GetFirstPlugin
const PluginDescriptor * GetFirstPlugin(int type)
Definition: PluginManager.cpp:2544
ID_ShowEnabled
@ ID_ShowEnabled
Definition: PluginManager.cpp:399
KEY_EFFECTTYPE_PROCESS
#define KEY_EFFECTTYPE_PROCESS
Definition: PluginManager.cpp:1371
ItemData::stateWidth
int stateWidth
Definition: PluginManager.cpp:391
ImporterInterface::GetSupportedExtensions
virtual FileExtensions GetSupportedExtensions()=0
ComponentInterface
ComponentInterface provides name / vendor / version functions to identify plugins....
Definition: ComponentInterface.h:121
PluginManager::IsPluginRegistered
bool IsPluginRegistered(const PluginPath &path) override
Definition: PluginManager.cpp:1438
PluginDescriptor::~PluginDescriptor
virtual ~PluginDescriptor()
Definition: PluginManager.cpp:1101
PluginTypeExporter
@ PluginTypeExporter
Definition: PluginManager.h:38
PluginDescriptor::IsEffectDefault
bool IsEffectDefault() const
Definition: PluginManager.cpp:1257
PluginDescriptor::IsValid
bool IsValid() const
Definition: PluginManager.cpp:1190
TranslatableString::MSGID
Identifier MSGID() const
Definition: Types.h:335
PluginDescriptor::SetEnabled
void SetEnabled(bool enable)
Definition: PluginManager.cpp:1230
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2406
PluginRegistrationDialog::mLongestPath
PluginPath mLongestPath
Definition: PluginManager.cpp:454
PluginDescriptor::SetVendor
void SetVendor(const wxString &vendor)
Definition: PluginManager.cpp:1225
KEY_EFFECTTYPE_HIDDEN
#define KEY_EFFECTTYPE_HIDDEN
Definition: PluginManager.cpp:1373
ItemData::path
PluginPath path
Definition: PluginManager.cpp:386
PluginDescriptor::mEffectAutomatable
bool mEffectAutomatable
Definition: PluginManager.h:151
PluginDescriptor::GetPath
const PluginPath & GetPath() const
Definition: PluginManager.cpp:1165
REGVERCUR
#define REGVERCUR
Definition: PluginManager.cpp:1343
STATE_New
@ STATE_New
Definition: PluginManager.cpp:377
PluginRegistrationDialog::RegenerateEffectsList
void RegenerateEffectsList(int iShowWhat)
Definition: PluginManager.cpp:716
PluginManager::RemoveSharedConfigSubgroup
bool RemoveSharedConfigSubgroup(const PluginID &ID, const RegistryPath &group) override
Definition: PluginManager.cpp:1622
Prefs.h
PluginDescriptor::SetVersion
void SetVersion(const wxString &version)
Definition: PluginManager.cpp:1220
PluginDescriptor::SetEffectLegacy
void SetEffectLegacy(bool legacy)
Definition: PluginManager.cpp:1297
ShuttleGuiBase::AddPrompt
void AddPrompt(const TranslatableString &Prompt, int wrapWidth=0)
Right aligned text string.
Definition: ShuttleGui.cpp:231
PluginManager::ShowManager
bool ShowManager(wxWindow *parent, EffectType type=EffectTypeNone)
Definition: PluginManager.cpp:2478
RegistryPath
wxString RegistryPath
Definition: Types.h:261
ComponentInterface::GetName
TranslatableString GetName()
Definition: PluginManager.cpp:3233
PluginManager::ConvertID
wxString ConvertID(const PluginID &ID)
Definition: PluginManager.cpp:3086
PluginManager::GetSubgroups
bool GetSubgroups(const RegistryPath &group, RegistryPaths &subgroups)
Definition: PluginManager.cpp:2828
TranslatableString::Join
TranslatableString & Join(TranslatableString arg, const wxString &separator={}) &
Definition: Internat.cpp:393
PluginManager::GetNextPluginForEffectType
const PluginDescriptor * GetNextPluginForEffectType(EffectType type)
Definition: PluginManager.cpp:2613
PluginTypeAudacityCommand
@ PluginTypeAudacityCommand
Definition: PluginManager.h:37
PluginManager::PrivateKey
RegistryPath PrivateKey(const PluginID &ID, const RegistryPath &group, const RegistryPath &key)
Definition: PluginManager.cpp:3073
ModuleManager::CreateProviderInstance
ModuleInterface * CreateProviderInstance(const PluginID &provider, const PluginPath &path)
Definition: ModuleManager.cpp:561
ComponentInterface::GetVersion
virtual wxString GetVersion()=0
STATE_Disabled
@ STATE_Disabled
Definition: PluginManager.cpp:376
EffectType
EffectType
Definition: EffectInterface.h:55
safenew
#define safenew
Definition: MemoryX.h:8
settings
static Settings & settings()
Definition: TrackInfo.cpp:87
PluginManager::LoadGroup
void LoadGroup(FileConfig *pRegistry, PluginType type)
Definition: PluginManager.cpp:2013
PluginManager::GetNextPlugin
const PluginDescriptor * GetNextPlugin(int type)
Definition: PluginManager.cpp:2568
KEY_EFFECTTYPE_TOOL
#define KEY_EFFECTTYPE_TOOL
Definition: PluginManager.cpp:1372
ItemData::name
wxString name
Definition: PluginManager.cpp:385
PluginManager::PrivateGroup
RegistryPath PrivateGroup(const PluginID &ID, const RegistryPath &group)
Definition: PluginManager.cpp:3059
PluginRegistrationDialog::OnClearAll
void OnClearAll(wxCommandEvent &evt)
Definition: PluginManager.cpp:926
EffectDefinitionInterface::GetFamily
virtual EffectFamilySymbol GetFamily()=0
PluginDescriptor::mImporterExtensions
FileExtensions mImporterExtensions
Definition: PluginManager.h:156
PluginManager::Terminate
void Terminate()
Definition: PluginManager.cpp:1791
PlatformCompatibility::GetExecutablePath
static const FilePath & GetExecutablePath()
Definition: PlatformCompatibility.cpp:33
END_EVENT_TABLE
END_EVENT_TABLE()
PluginTypeEffect
@ PluginTypeEffect
Definition: PluginManager.h:36
PluginManager::GetPlugin
const PluginDescriptor * GetPlugin(const PluginID &ID)
Definition: PluginManager.cpp:2534
PluginDescriptor::mEffectType
EffectType mEffectType
Definition: PluginManager.h:146
PluginManager::GetPluginEnabledSetting
RegistryPath GetPluginEnabledSetting(const PluginID &ID)
Definition: PluginManager.cpp:1407
KEY_VALID
#define KEY_VALID
Definition: PluginManager.cpp:1360
ArrayOf< char >
REGVERKEY
#define REGVERKEY
Definition: PluginManager.cpp:1342
PluginDescriptor::SetInstance
void SetInstance(ComponentInterface *instance)
Definition: PluginManager.cpp:1137
ID_ShowDisabled
@ ID_ShowDisabled
Definition: PluginManager.cpp:400
PluginDescriptor::SetEffectDefault
void SetEffectDefault(bool dflt)
Definition: PluginManager.cpp:1292
STATE_COUNT
@ STATE_COUNT
Definition: PluginManager.cpp:379
PluginManager::SetSharedConfig
bool SetSharedConfig(const PluginID &ID, const RegistryPath &group, const RegistryPath &key, const wxString &value) override
Definition: PluginManager.cpp:1597
PluginManager::HasSharedConfigGroup
bool HasSharedConfigGroup(const PluginID &ID, const RegistryPath &group)
Definition: PluginManager.cpp:1562
PluginTypeStub
@ PluginTypeStub
Definition: PluginManager.h:35
EffectDefinitionInterface::IsDefault
virtual bool IsDefault()=0
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:638
PluginDescriptor::SetPluginType
void SetPluginType(PluginType type)
Definition: PluginManager.cpp:1195
PluginDescriptor::SetID
void SetID(const PluginID &ID)
Definition: PluginManager.cpp:1200
PluginRegistrationDialog::SetState
void SetState(int i, bool toggle, bool state=true)
Definition: PluginManager.cpp:777
PluginDescriptor::mEffectFamily
wxString mEffectFamily
Definition: PluginManager.h:145
PluginManager::GetSettings
FileConfig * GetSettings()
Definition: PluginManager.cpp:2780
PluginManager::SetConfig
bool SetConfig(const RegistryPath &key, const wxString &value)
Definition: PluginManager.cpp:2921
padc
static const char padc
Definition: PluginManager.cpp:3111
FileConfig::GetPath
virtual const wxString & GetPath() const wxOVERRIDE
Definition: FileConfig.cpp:106
PluginRegistrationDialog::OnOK
void OnOK(wxCommandEvent &evt)
Definition: PluginManager.cpp:972