Audacity  3.2.0
EffectUI.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  EffectUI.cpp
6 
7  Leland Lucius
8 
9  Audacity(R) is copyright (c) 1999-2008 Audacity Team.
10  License: GPL v2 or later. See License.txt.
11 
12 **********************************************************************/
13 
14 
15 #include "EffectUI.h"
16 
17 #include "widgets/BasicMenu.h"
18 #include "Effect.h"
19 #include "EffectManager.h"
20 #include "PluginManager.h"
21 #include "../ProjectHistory.h"
22 #include "../ProjectWindowBase.h"
23 #include "../TrackPanelAx.h"
24 #include "RealtimeEffectManager.h"
26 
27 static PluginID GetID(Effect &effect)
28 {
29  return PluginManager::GetID(&effect.GetDefinition());
30 }
31 
33 //
34 // EffectPanel
35 //
37 
38 class EffectPanel final : public wxPanelWrapper
39 {
40 public:
41  EffectPanel(wxWindow *parent)
42  : wxPanelWrapper(parent)
43  {
44  // This fools NVDA into not saying "Panel" when the dialog gets focus
47 
48  mAcceptsFocus = true;
49  }
50 
51  virtual ~EffectPanel()
52  {
53  }
54 
55  // ============================================================================
56  // wxWindow implementation
57  // ============================================================================
58 
59  bool AcceptsFocus() const override
60  {
61  return mAcceptsFocus;
62  }
63 
64  // So that wxPanel is not included in Tab traversal, when required - see wxWidgets bug 15581
65  bool AcceptsFocusFromKeyboard() const override
66  {
67  return mAcceptsFocus;
68  }
69 
70  // ============================================================================
71  // EffectPanel implementation
72  // ============================================================================
73  void SetAccept(bool accept)
74  {
75  mAcceptsFocus = accept;
76  }
77 
78 private:
80 };
81 
83 //
84 // EffectUIHost
85 //
87 
88 #include "../../images/Effect.h"
89 #include "../AudioIO.h"
90 #include "../CommonCommandFlags.h"
91 #include "../Menus.h"
92 #include "../prefs/GUISettings.h" // for RTL_WORKAROUND
93 #include "Project.h"
94 #include "../ProjectAudioManager.h"
95 #include "../ShuttleGui.h"
96 #include "ViewInfo.h"
97 #include "../commands/AudacityCommand.h"
98 #include "../commands/CommandContext.h"
99 #include "../widgets/AudacityMessageBox.h"
100 #include "../widgets/HelpSystem.h"
101 
102 #include <wx/bmpbuttn.h>
103 #include <wx/checkbox.h>
104 #include <wx/dcclient.h>
105 #include <wx/dcmemory.h>
106 #include <wx/menu.h>
107 #include <wx/settings.h>
108 #include <wx/sizer.h>
109 #include <wx/textctrl.h>
110 
111 #if defined(__WXMAC__)
112 #include <Cocoa/Cocoa.h>
113 #endif
114 
115 static const int kDummyID = 20000;
116 static const int kSaveAsID = 20001;
117 static const int kImportID = 20002;
118 static const int kExportID = 20003;
119 static const int kDefaultsID = 20004;
120 static const int kOptionsID = 20005;
121 static const int kUserPresetsDummyID = 20006;
122 static const int kDeletePresetDummyID = 20007;
123 static const int kMenuID = 20100;
124 static const int kEnableID = 20101;
125 static const int kPlayID = 20102;
126 static const int kRewindID = 20103;
127 static const int kFFwdID = 20104;
128 static const int kPlaybackID = 20105;
129 static const int kCaptureID = 20106;
130 static const int kUserPresetsID = 21000;
131 static const int kDeletePresetID = 22000;
132 static const int kFactoryPresetsID = 23000;
133 
134 BEGIN_EVENT_TABLE(EffectUIHost, wxDialogWrapper)
135 EVT_INIT_DIALOG(EffectUIHost::OnInitDialog)
136 EVT_ERASE_BACKGROUND(EffectUIHost::OnErase)
137 EVT_PAINT(EffectUIHost::OnPaint)
138 EVT_CLOSE(EffectUIHost::OnClose)
144 EVT_CHECKBOX(kEnableID, EffectUIHost::OnEnable)
157 
158 EffectUIHost::EffectUIHost(wxWindow *parent,
159  AudacityProject &project,
160  Effect &effect,
161  EffectUIClientInterface &client)
162 : wxDialogWrapper(parent, wxID_ANY, effect.GetName(),
163  wxDefaultPosition, wxDefaultSize,
164  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX)
165 , mEffect{ effect }
166 , mClient{ client }
167 {
168 #if defined(__WXMAC__)
169  // Make sure the effect window actually floats above the main window
170  [ [((NSView *)GetHandle()) window] setLevel:NSFloatingWindowLevel];
171 #endif
172 
173  SetName( effect.GetName() );
174  SetExtraStyle(GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
175 
176  mParent = parent;
177  mClient = client;
178 
179  mProject = &project;
180 
181  mInitialized = false;
182  mSupportsRealtime = false;
183 
184  mDisableTransport = false;
185 
186  mEnabled = true;
187 
188  mPlayPos = 0.0;
189 }
190 
192 {
193  wxASSERT(mClosed);
194 }
195 
196 // ============================================================================
197 // wxWindow implementation
198 // ============================================================================
199 
201 {
202  return mEffect.TransferDataToWindow();
203 }
204 
206 {
208 }
209 
210 // ============================================================================
211 // wxDialog implementation
212 // ============================================================================
213 
215 {
216 #if defined(__WXMSW__)
217  // Swap the Close and Apply buttons
218  wxSizer *sz = mApplyBtn->GetContainingSizer();
219  wxASSERT(mApplyBtn->GetParent()); // To justify safenew
220  wxButton *apply = safenew wxButton(mApplyBtn->GetParent(), wxID_APPLY);
221  sz->Replace(mCloseBtn, apply);
222  sz->Replace(mApplyBtn, mCloseBtn);
223  sz->Layout();
224  mApplyBtn->Destroy();
225  mApplyBtn = apply;
226  mApplyBtn->SetDefault();
227  mApplyBtn->SetLabel(wxGetStockLabel(wxID_OK, 0));
228  mCloseBtn->SetLabel(wxGetStockLabel(wxID_CANCEL, 0));
229 #else
230  mApplyBtn->SetLabel(wxGetStockLabel(wxID_OK));
231  mCloseBtn->SetLabel(wxGetStockLabel(wxID_CANCEL));
232 #endif
233 
234  Layout();
235 
236  return wxDialogWrapper::ShowModal();
237 }
238 
239 // ============================================================================
240 // EffectUIHost implementation
241 // ============================================================================
242 
243 wxPanel *EffectUIHost::BuildButtonBar(wxWindow *parent)
244 {
248 
249  int margin = 0;
250 #if defined(__WXMAC__)
251  margin = 3; // I'm sure it's needed because of the order things are created...
252 #endif
253 
254  const auto bar = safenew wxPanelWrapper(parent, wxID_ANY);
255 
256  // This fools NVDA into not saying "Panel" when the dialog gets focus
257  bar->SetName(TranslatableString::Inaudible);
258  bar->SetLabel(TranslatableString::Inaudible);
259 
260  ShuttleGui S{ bar, eIsCreating,
261  false /* horizontal */,
262  { -1, -1 } /* minimum size */
263  };
264  {
265  S.SetBorder( margin );
266 
267  if (!mIsGUI)
268  {
269  mMenuBtn = S.Id( kMenuID )
270  .ToolTip(XO("Manage presets and options"))
271  .AddButton( XXO("&Manage"), wxALIGN_CENTER | wxTOP | wxBOTTOM );
272  }
273  else
274  {
275  mMenuBtn = S.Id( kMenuID )
276  .ToolTip(XO("Manage presets and options"))
277  .Name(XO("&Manage"))
278  .AddBitmapButton( CreateBitmap(effect_menu_xpm, true, true) );
279  mMenuBtn->SetBitmapPressed(CreateBitmap(effect_menu_xpm, false, true));
280  }
281 
282  S.AddSpace( 5, 5 );
283 
284  if (!mIsBatch)
285  {
286  if (!mIsGUI)
287  {
288  if (mSupportsRealtime)
289  {
290  mPlayToggleBtn = S.Id( kPlayID )
291  .ToolTip(XO("Start and stop playback"))
292  .AddButton( XXO("Start &Playback"),
293  wxALIGN_CENTER | wxTOP | wxBOTTOM );
294  }
295  else if (
298  {
299  mPlayToggleBtn = S.Id( kPlayID )
300  .ToolTip(XO("Preview effect"))
301  .AddButton( XXO("&Preview"),
302  wxALIGN_CENTER | wxTOP | wxBOTTOM );
303  }
304  }
305  else
306  {
307  mPlayBM = CreateBitmap(effect_play_xpm, true, false);
308  mPlayDisabledBM = CreateBitmap(effect_play_disabled_xpm, true, true);
309  mStopBM = CreateBitmap(effect_stop_xpm, true, false);
310  mStopDisabledBM = CreateBitmap(effect_stop_disabled_xpm, true, false);
311  mPlayBtn = S.Id( kPlayID ).AddBitmapButton( mPlayBM );
312  mPlayBtn->SetBitmapDisabled(mPlayDisabledBM);
313  mPlayBtn->SetBitmapPressed(CreateBitmap(effect_play_xpm, false, true));
314  if (!mSupportsRealtime)
315  {
316  mPlayBtn->SetToolTip(_("Preview effect"));
317 #if defined(__WXMAC__)
318  mPlayBtn->SetName(_("Preview effect"));
319 #else
320  mPlayBtn->SetLabel(_("&Preview effect"));
321 #endif
322  }
323  }
324 
325  if (mSupportsRealtime)
326  {
327  if (!mIsGUI)
328  {
329  mRewindBtn = S.Id( kRewindID )
330  .ToolTip(XO("Skip backward"))
331  .AddButton( XXO("Skip &Backward"),
332  wxALIGN_CENTER | wxTOP | wxBOTTOM );
333  }
334  else
335  {
336  mRewindBtn = S.Id( kRewindID )
337  .ToolTip(XO("Skip backward"))
338  .Name(XO("Skip &Backward"))
339  .AddBitmapButton( CreateBitmap(
340  effect_rewind_xpm, true, true) );
341  mRewindBtn->SetBitmapDisabled(
342  CreateBitmap(effect_rewind_disabled_xpm, true, false));
343  mRewindBtn->SetBitmapPressed(CreateBitmap(effect_rewind_xpm, false, true));
344  }
345 
346  if (!mIsGUI)
347  {
348  mFFwdBtn = S.Id( kFFwdID )
349  .ToolTip(XO("Skip forward"))
350  .AddButton( XXO("Skip &Forward"),
351  wxALIGN_CENTER | wxTOP | wxBOTTOM );
352  }
353  else
354  {
355  mFFwdBtn = S.Id( kFFwdID )
356  .ToolTip(XO("Skip forward"))
357  .Name(XO("Skip &Forward"))
358  .AddBitmapButton( CreateBitmap(
359  effect_ffwd_xpm, true, true) );
360  mFFwdBtn->SetBitmapDisabled(
361  CreateBitmap(effect_ffwd_disabled_xpm, true, false));
362  mFFwdBtn->SetBitmapPressed(CreateBitmap(effect_ffwd_xpm, false, true));
363  }
364 
365  S.AddSpace( 5, 5 );
366 
367  mEnableCb = S.Id( kEnableID )
368  .Position(wxALIGN_CENTER | wxTOP | wxBOTTOM)
369  .Name(XO("Enable"))
370  .AddCheckBox( XXO("&Enable"), mEnabled );
371  //
372  }
373  }
374  }
375 
376  bar->GetSizer()->SetSizeHints( bar );
377 
378  return bar;
379 }
380 
382 {
383  {
384  auto gAudioIO = AudioIO::Get();
385  mDisableTransport = !gAudioIO->IsAvailable(*mProject);
386  mPlaying = gAudioIO->IsStreamActive(); // not exactly right, but will suffice
387  mCapturing = gAudioIO->IsStreamActive() && gAudioIO->GetNumCaptureChannels() > 0 && !gAudioIO->IsMonitoring();
388  }
389 
390  // Build a "host" dialog, framing a panel that the client fills in.
391  // The frame includes buttons to preview, apply, load and save presets, etc.
392  EffectPanel *w {};
393  ShuttleGui S{ this, eIsCreating };
394  {
395  S.StartHorizontalLay( wxEXPAND );
396  {
397  // Make the panel for the client
398  Destroy_ptr<EffectPanel> uw{ safenew EffectPanel( S.GetParent() ) };
399  RTL_WORKAROUND(uw.get());
400 
401  // Try to give the window a sensible default/minimum size
402  uw->SetMinSize(wxSize(wxMax(600, mParent->GetSize().GetWidth() * 2 / 3),
403  mParent->GetSize().GetHeight() / 2));
404 
405  // Let the client add things to the panel
406  ShuttleGui S1{ uw.get(), eIsCreating };
407  if (!mClient.PopulateUI(S1))
408  {
409  return false;
410  }
411 
412  S.Prop( 1 )
413  .Position(wxEXPAND)
414  .AddWindow((w = uw.release()));
415  }
416  S.EndHorizontalLay();
417 
418  S.StartPanel();
419  {
420  const auto bar = BuildButtonBar( S.GetParent() );
421 
422  long buttons;
423  if ( mEffect.ManualPage().empty() && mEffect.HelpPage().empty()) {
424  buttons = eApplyButton | eCloseButton;
425  this->SetAcceleratorTable(wxNullAcceleratorTable);
426  }
427  else {
428  buttons = eApplyButton | eCloseButton | eHelpButton;
429  wxAcceleratorEntry entries[1];
430 #if defined(__WXMAC__)
431  // Is there a standard shortcut on Mac?
432 #else
433  entries[0].Set(wxACCEL_NORMAL, (int) WXK_F1, wxID_HELP);
434 #endif
435  wxAcceleratorTable accel(1, entries);
436  this->SetAcceleratorTable(accel);
437  }
438 
439  if (mEffect.EnablesDebug())
440  buttons |= eDebugButton;
441 
442  S.AddStandardButtons(buttons, bar);
443  }
444  S.EndPanel();
445  }
446 
447  Layout();
448  Fit();
449  Center();
450 
451  mApplyBtn = (wxButton *) FindWindow(wxID_APPLY);
452  mCloseBtn = (wxButton *) FindWindow(wxID_CANCEL);
453 
454  UpdateControls();
455 
456  w->SetAccept(!mIsGUI);
457  (!mIsGUI ? w : FindWindow(wxID_APPLY))->SetFocus();
458 
459  LoadUserPresets();
460 
462 
463  SetMinSize(GetSize());
464  return true;
465 }
466 
467 void EffectUIHost::OnInitDialog(wxInitDialogEvent & evt)
468 {
469  // Do default handling
470  wxDialogWrapper::OnInitDialog(evt);
471 
472 #if wxCHECK_VERSION(3, 0, 0)
473  //#warning "check to see if this still needed in wx3"
474 #endif
475 
476  // Pure hackage coming down the pike...
477  //
478  // I have no idea why, but if a wxTextCtrl is the first control in the
479  // panel, then its contents will not be automatically selected when the
480  // dialog is displayed.
481  //
482  // So, we do the selection manually.
483  wxTextCtrl *focused = wxDynamicCast(FindFocus(), wxTextCtrl);
484  if (focused)
485  {
486  focused->SelectAll();
487  }
488 }
489 
490 void EffectUIHost::OnErase(wxEraseEvent & WXUNUSED(evt))
491 {
492  // Ignore it
493 }
494 
495 void EffectUIHost::OnPaint(wxPaintEvent & WXUNUSED(evt))
496 {
497  wxPaintDC dc(this);
498 
499  dc.Clear();
500 }
501 
502 void EffectUIHost::OnClose(wxCloseEvent & WXUNUSED(evt))
503 {
504  DoCancel();
505 
506  CleanupRealtime();
507 
508  Hide();
509 
510  if (mNeedsResume)
511  Resume();
512  mClient.CloseUI();
513 
514  Destroy();
515 #if wxDEBUG_LEVEL
516  mClosed = true;
517 #endif
518 }
519 
520 void EffectUIHost::OnApply(wxCommandEvent & evt)
521 {
522  auto &project = *mProject;
523 
524  // On wxGTK (wx2.8.12), the default action is still executed even if
525  // the button is disabled. This appears to affect all wxDialogs, not
526  // just our Effects dialogs. So, this is a only temporary workaround
527  // for legacy effects that disable the OK button. Hopefully this has
528  // been corrected in wx3.
529  if (!FindWindow(wxID_APPLY)->IsEnabled())
530  {
531  return;
532  }
533 
534  // Honor the "select all if none" preference...a little hackish, but whatcha gonna do...
535  if (!mIsBatch &&
538  ViewInfo::Get( project ).selectedRegion.isPoint())
539  {
540  auto flags = AlwaysEnabledFlag;
541  bool allowed =
543  mEffect.GetName(),
544  flags,
546  if (!allowed)
547  return;
548  }
549 
550  if (!mClient.ValidateUI())
551  {
552  return;
553  }
554 
555  // This will take care of calling TransferDataFromWindow() for an effect.
557  {
558  return;
559  }
560 
561  if (IsModal())
562  {
563  mDismissed = true;
564 
565  EndModal(evt.GetId());
566 
567  Close();
568 
569  return;
570  }
571 
572  // Progress dialog no longer yields, so this "shouldn't" be necessary (yet to be proven
573  // for sure), but it is a nice visual cue that something is going on.
574  mApplyBtn->Disable();
575  auto cleanup = finally( [&] { mApplyBtn->Enable(); } );
576 
577  CommandContext context( project );
578  // This is absolute hackage...but easy and I can't think of another way just now.
579  //
580  // It should callback to the EffectManager to kick off the processing
581  EffectUI::DoEffect(GetID(mEffect), context,
583 }
584 
586 {
587  if (!mDismissed) {
588  if (IsModal())
589  EndModal(0);
590  else
591  Hide();
592 
593  mDismissed = true;
594  }
595 }
596 
597 void EffectUIHost::OnCancel(wxCommandEvent & WXUNUSED(evt))
598 {
599  DoCancel();
600  Close();
601 }
602 
603 void EffectUIHost::OnHelp(wxCommandEvent & WXUNUSED(event))
604 {
606  // Old ShowHelp required when there is no on-line manual.
607  // Always use default web browser to allow full-featured HTML pages.
608  HelpSystem::ShowHelp(FindWindow(wxID_HELP), mEffect.HelpPage(), wxEmptyString, true, true);
609  }
610  else {
611  // otherwise use the NEW ShowHelp
612  HelpSystem::ShowHelp(FindWindow(wxID_HELP), mEffect.ManualPage(), true);
613  }
614 }
615 
616 void EffectUIHost::OnDebug(wxCommandEvent & evt)
617 {
618  OnApply(evt);
619 }
620 
621 void EffectUIHost::OnMenu(wxCommandEvent & WXUNUSED(evt))
622 {
623  wxMenu menu;
624  menu.Bind(wxEVT_MENU, [](auto&){}, kUserPresetsDummyID);
625  menu.Bind(wxEVT_MENU, [](auto&){}, kDeletePresetDummyID);
626  LoadUserPresets();
627 
628  if (mUserPresets.size() == 0)
629  {
630  menu.Append(kUserPresetsDummyID, _("User Presets"))->Enable(false);
631  }
632  else
633  {
634  auto sub = std::make_unique<wxMenu>();
635  for (size_t i = 0, cnt = mUserPresets.size(); i < cnt; i++)
636  {
637  sub->Append(kUserPresetsID + i, mUserPresets[i]);
638  }
639  menu.Append(0, _("User Presets"), sub.release());
640  }
641 
642  menu.Append(kSaveAsID, _("Save Preset..."));
643 
644  if (mUserPresets.size() == 0)
645  {
646  menu.Append(kDeletePresetDummyID, _("Delete Preset"))->Enable(false);
647  }
648  else
649  {
650  auto sub = std::make_unique<wxMenu>();
651  for (size_t i = 0, cnt = mUserPresets.size(); i < cnt; i++)
652  {
653  sub->Append(kDeletePresetID + i, mUserPresets[i]);
654  }
655  menu.Append(0, _("Delete Preset"), sub.release());
656  }
657 
658  menu.AppendSeparator();
659 
661 
662  {
663  auto sub = std::make_unique<wxMenu>();
664  sub->Append(kDefaultsID, _("Defaults"));
665  if (factory.size() > 0)
666  {
667  sub->AppendSeparator();
668  for (size_t i = 0, cnt = factory.size(); i < cnt; i++)
669  {
670  auto label = factory[i];
671  if (label.empty())
672  {
673  label = _("None");
674  }
675 
676  sub->Append(kFactoryPresetsID + i, label);
677  }
678  }
679  menu.Append(0, _("Factory Presets"), sub.release());
680  }
681 
682  menu.AppendSeparator();
683  menu.Append(kImportID, _("Import..."))->Enable(mClient.CanExportPresets());
684  menu.Append(kExportID, _("Export..."))->Enable(mClient.CanExportPresets());
685  menu.AppendSeparator();
686  menu.Append(kOptionsID, _("Options..."))->Enable(mClient.HasOptions());
687  menu.AppendSeparator();
688 
689  {
690  auto sub = std::make_unique<wxMenu>();
691 
692  sub->Append(kDummyID, wxString::Format(_("Type: %s"),
693  ::wxGetTranslation( mEffect.GetFamily().Translation() )));
694  sub->Append(kDummyID, wxString::Format(_("Name: %s"), mEffect.GetName().Translation()));
695  sub->Append(kDummyID, wxString::Format(_("Version: %s"), mEffect.GetVersion()));
696  sub->Append(kDummyID, wxString::Format(_("Vendor: %s"), mEffect.GetVendor().Translation()));
697  sub->Append(kDummyID, wxString::Format(_("Description: %s"), mEffect.GetDescription().Translation()));
698  sub->Bind(wxEVT_MENU, [](auto&){}, kDummyID);
699 
700  menu.Append(0, _("About"), sub.release());
701  }
702 
703  wxWindow *btn = FindWindow(kMenuID);
704  wxRect r = btn->GetRect();
705  BasicMenu::Handle{ &menu }.Popup(
707  { r.GetLeft(), r.GetBottom() }
708  );
709 }
710 
712 {
713  if (!mClient.ValidateUI()) {
714  // If we're previewing we should still be able to stop playback
715  // so don't disable transport buttons.
716  // mEffect->EnableApply(false); // currently this would also disable transport buttons.
717  // The preferred behaviour is currently undecided, so for now
718  // just disallow enabling until settings are valid.
719  mEnabled = false;
720  mEnableCb->SetValue(mEnabled);
721  return;
722  }
724 }
725 
726 void EffectUIHost::OnEnable(wxCommandEvent & WXUNUSED(evt))
727 {
728  mEnabled = mEnableCb->GetValue();
729 
730  if (mEnabled) {
731  Resume();
732  mNeedsResume = false;
733  }
734  else
735  {
737  mNeedsResume = true;
738  }
739 
740  UpdateControls();
741 }
742 
743 void EffectUIHost::OnPlay(wxCommandEvent & WXUNUSED(evt))
744 {
745  if (!mSupportsRealtime)
746  {
748  {
749  return;
750  }
751 
752  mEffect.Preview(false);
753 
754  return;
755  }
756 
757  if (mPlaying)
758  {
759  auto gAudioIO = AudioIO::Get();
760  mPlayPos = gAudioIO->GetStreamTime();
761  auto &projectAudioManager = ProjectAudioManager::Get( *mProject );
762  projectAudioManager.Stop();
763  }
764  else
765  {
766  auto &viewInfo = ViewInfo::Get( *mProject );
767  const auto &selectedRegion = viewInfo.selectedRegion;
768  const auto &playRegion = viewInfo.playRegion;
769  if ( playRegion.Active() )
770  {
771  mRegion.setTimes(playRegion.GetStart(), playRegion.GetEnd());
772  mPlayPos = mRegion.t0();
773  }
774  else if (selectedRegion.t0() != mRegion.t0() ||
775  selectedRegion.t1() != mRegion.t1())
776  {
777  mRegion = selectedRegion;
778  mPlayPos = mRegion.t0();
779  }
780 
781  if (mPlayPos > mRegion.t1())
782  {
783  mPlayPos = mRegion.t1();
784  }
785 
786  auto &projectAudioManager = ProjectAudioManager::Get( *mProject );
787  projectAudioManager.PlayPlayRegion(
791  }
792 }
793 
794 void EffectUIHost::OnRewind(wxCommandEvent & WXUNUSED(evt))
795 {
796  if (mPlaying)
797  {
798  auto gAudioIO = AudioIO::Get();
799  double seek;
800  gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &seek, 1.0);
801 
802  double pos = gAudioIO->GetStreamTime();
803  if (pos - seek < mRegion.t0())
804  {
805  seek = pos - mRegion.t0();
806  }
807 
808  gAudioIO->SeekStream(-seek);
809  }
810  else
811  {
812  mPlayPos = mRegion.t0();
813  }
814 }
815 
816 void EffectUIHost::OnFFwd(wxCommandEvent & WXUNUSED(evt))
817 {
818  if (mPlaying)
819  {
820  double seek;
821  gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &seek, 1.0);
822 
823  auto gAudioIO = AudioIO::Get();
824  double pos = gAudioIO->GetStreamTime();
825  if (mRegion.t0() < mRegion.t1() && pos + seek > mRegion.t1())
826  {
827  seek = mRegion.t1() - pos;
828  }
829 
830  gAudioIO->SeekStream(seek);
831  }
832  else
833  {
834  // It allows to play past end of selection...probably useless
835  mPlayPos = mRegion.t1();
836  }
837 }
838 
840 {
841  if (evt.on)
842  {
843  if (evt.pProject != mProject)
844  {
845  mDisableTransport = true;
846  }
847  else
848  {
849  mPlaying = true;
850  }
851  }
852  else
853  {
854  mDisableTransport = false;
855  mPlaying = false;
856  }
857 
858  if (mPlaying)
859  {
860  mRegion = ViewInfo::Get( *mProject ).selectedRegion;
861  mPlayPos = mRegion.t0();
862  }
863 
864  UpdateControls();
865 }
866 
868 {
869  if (evt.on)
870  {
871  if (evt.pProject != mProject)
872  {
873  mDisableTransport = true;
874  }
875  else
876  {
877  mCapturing = true;
878  }
879  }
880  else
881  {
882  mDisableTransport = false;
883  mCapturing = false;
884  }
885 
886  UpdateControls();
887 }
888 
889 void EffectUIHost::OnUserPreset(wxCommandEvent & evt)
890 {
891  int preset = evt.GetId() - kUserPresetsID;
892 
894 
895  return;
896 }
897 
898 void EffectUIHost::OnFactoryPreset(wxCommandEvent & evt)
899 {
901 
902  return;
903 }
904 
905 void EffectUIHost::OnDeletePreset(wxCommandEvent & evt)
906 {
907  auto preset = mUserPresets[evt.GetId() - kDeletePresetID];
908 
909  int res = AudacityMessageBox(
910  XO("Are you sure you want to delete \"%s\"?").Format( preset ),
911  XO("Delete Preset"),
912  wxICON_QUESTION | wxYES_NO);
913  if (res == wxYES)
914  {
917  mEffect.GetUserPresetsGroup(preset));
918  }
919 
920  LoadUserPresets();
921 
922  return;
923 }
924 
925 void EffectUIHost::OnSaveAs(wxCommandEvent & WXUNUSED(evt))
926 {
927  wxTextCtrl *text;
928  wxString name;
929  wxDialogWrapper dlg(this, wxID_ANY, XO("Save Preset"));
930 
931  ShuttleGui S(&dlg, eIsCreating);
932 
933  S.StartPanel();
934  {
935  S.StartVerticalLay(1);
936  {
937  S.StartHorizontalLay(wxALIGN_LEFT, 0);
938  {
939  text = S.AddTextBox(XXO("Preset name:"), name, 30);
940  }
941  S.EndHorizontalLay();
942  S.SetBorder(10);
943  S.AddStandardButtons();
944  }
945  S.EndVerticalLay();
946  }
947  S.EndPanel();
948 
949  dlg.SetSize(dlg.GetSizer()->GetMinSize());
950  dlg.Center();
951  dlg.Fit();
952 
953  while (true)
954  {
955  int rc = dlg.ShowModal();
956 
957  if (rc != wxID_OK)
958  {
959  break;
960  }
961 
962  name = text->GetValue();
963  if (name.empty())
964  {
966  this,
967  XO("You must specify a name"),
968  XO("Save Preset") );
969  md.Center();
970  md.ShowModal();
971  continue;
972  }
973 
974  if ( make_iterator_range( mUserPresets ).contains( name ) )
975  {
977  this,
978  XO("Preset already exists.\n\nReplace?"),
979  XO("Save Preset"),
980  wxYES_NO | wxCANCEL | wxICON_EXCLAMATION );
981  md.Center();
982  int choice = md.ShowModal();
983  if (choice == wxID_CANCEL)
984  {
985  break;
986  }
987 
988  if (choice == wxID_NO)
989  {
990  continue;
991  }
992  }
993 
995  LoadUserPresets();
996 
997  break;
998  }
999 
1000  return;
1001 }
1002 
1003 void EffectUIHost::OnImport(wxCommandEvent & WXUNUSED(evt))
1004 {
1006 
1007  LoadUserPresets();
1008 
1009  return;
1010 }
1011 
1012 void EffectUIHost::OnExport(wxCommandEvent & WXUNUSED(evt))
1013 {
1014  // may throw
1015  // exceptions are handled in AudacityApp::OnExceptionInMainLoop
1017 
1018  return;
1019 }
1020 
1021 void EffectUIHost::OnOptions(wxCommandEvent & WXUNUSED(evt))
1022 {
1023  mClient.ShowOptions();
1024 
1025  return;
1026 }
1027 
1028 void EffectUIHost::OnDefaults(wxCommandEvent & WXUNUSED(evt))
1029 {
1031 
1032  return;
1033 }
1034 
1035 wxBitmap EffectUIHost::CreateBitmap(const char * const xpm[], bool up, bool pusher)
1036 {
1037  wxMemoryDC dc;
1038  wxBitmap pic(xpm);
1039 
1040  wxBitmap mod(pic.GetWidth() + 6, pic.GetHeight() + 6, 24);
1041  dc.SelectObject(mod);
1042 
1043 #if defined(__WXGTK__)
1044  wxColour newColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BACKGROUND);
1045 #else
1046  wxColour newColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
1047 #endif
1048 
1049  dc.SetBackground(wxBrush(newColour));
1050  dc.Clear();
1051 
1052  int offset = 3;
1053  if (pusher)
1054  {
1055  if (!up)
1056  {
1057  offset += 1;
1058  }
1059  }
1060 
1061  dc.DrawBitmap(pic, offset, offset, true);
1062 
1063  dc.SelectObject(wxNullBitmap);
1064 
1065  return mod;
1066 }
1067 
1069 {
1070  if (mIsBatch)
1071  {
1072  return;
1073  }
1074 
1076  {
1077  // Don't allow focus to get trapped
1078  wxWindow *focus = FindFocus();
1079  if (focus == mRewindBtn || focus == mFFwdBtn || focus == mPlayBtn || focus == mEnableCb)
1080  {
1081  mCloseBtn->SetFocus();
1082  }
1083  }
1084 
1085  mApplyBtn->Enable(!mCapturing);
1086  if ((mEffect.GetType() != EffectTypeAnalyze) &&
1087  (mEffect.GetType() != EffectTypeTool) )
1088  {
1090  }
1091 
1092  if (mSupportsRealtime)
1093  {
1094  mRewindBtn->Enable(!(mCapturing || mDisableTransport));
1095  mFFwdBtn->Enable(!(mCapturing || mDisableTransport));
1096  mEnableCb->Enable(!(mCapturing || mDisableTransport));
1097 
1098  wxBitmapButton *bb;
1099 
1100  if (mPlaying)
1101  {
1102  if (!mIsGUI)
1103  {
1104  /* i18n-hint: The access key "&P" should be the same in
1105  "Stop &Playback" and "Start &Playback" */
1106  mPlayToggleBtn->SetLabel(_("Stop &Playback"));
1107  mPlayToggleBtn->Refresh();
1108  }
1109  else
1110  {
1111  bb = (wxBitmapButton *) mPlayBtn;
1112  bb->SetBitmapLabel(mStopBM);
1113  bb->SetBitmapDisabled(mStopDisabledBM);
1114  bb->SetToolTip(_("Stop"));
1115 #if defined(__WXMAC__)
1116  bb->SetName(_("Stop &Playback"));
1117 #else
1118  bb->SetLabel(_("Stop &Playback"));
1119 #endif
1120  }
1121  }
1122  else
1123  {
1124  if (!mIsGUI)
1125  {
1126  /* i18n-hint: The access key "&P" should be the same in
1127  "Stop &Playback" and "Start &Playback" */
1128  mPlayToggleBtn->SetLabel(_("Start &Playback"));
1129  mPlayToggleBtn->Refresh();
1130  }
1131  else
1132  {
1133  bb = (wxBitmapButton *) mPlayBtn;
1134  bb->SetBitmapLabel(mPlayBM);
1135  bb->SetBitmapDisabled(mPlayDisabledBM);
1136  bb->SetToolTip(_("Play"));
1137 #if defined(__WXMAC__)
1138  bb->SetName(_("Start &Playback"));
1139 #else
1140  bb->SetLabel(_("Start &Playback"));
1141 #endif
1142  }
1143  }
1144  }
1145 }
1146 
1148 {
1149  mUserPresets.clear();
1150 
1152  mEffect.GetUserPresetsGroup(wxEmptyString), mUserPresets);
1153 
1154  std::sort( mUserPresets.begin(), mUserPresets.end() );
1155 
1156  return;
1157 }
1158 
1160 {
1162  {
1164 
1165  AudioIO::Get()->Subscribe([this](AudioIOEvent event){
1166  switch (event.type) {
1167  case AudioIOEvent::PLAYBACK:
1168  OnPlayback(event); break;
1169  case AudioIOEvent::CAPTURE:
1170  OnCapture(event); break;
1171  default:
1172  break;
1173  }
1174  });
1175 
1176  mInitialized = true;
1177  }
1178 }
1179 
1181 {
1183  {
1185 
1186  mInitialized = false;
1187  }
1188 }
1189 
1190 wxDialog *EffectUI::DialogFactory( wxWindow &parent, EffectHostInterface &host,
1191  EffectUIClientInterface &client)
1192 {
1193  const auto pEffect = dynamic_cast< Effect* >( &host ); // TODO remove dynamic_cast
1194  if ( ! pEffect )
1195  return nullptr;
1196 
1197  // Make sure there is an associated project, whose lifetime will
1198  // govern the lifetime of the dialog, even when the dialog is
1199  // non-modal, as for realtime effects
1200  auto project = FindProjectFromWindow(&parent);
1201  if ( !project )
1202  return nullptr;
1203 
1205  safenew EffectUIHost{ &parent, *project, *pEffect, client} };
1206 
1207  if (dlg->Initialize())
1208  {
1209  // release() is safe because parent will own it
1210  return dlg.release();
1211  }
1212 
1213  return nullptr;
1214 };
1215 
1216 #include "PluginManager.h"
1217 #include "ProjectRate.h"
1218 #include "../ProjectWindow.h"
1219 #include "../SelectUtilities.h"
1220 #include "../TrackPanel.h"
1221 #include "../WaveTrack.h"
1222 #include "../commands/CommandManager.h"
1223 
1227 // parameters, whether to save the state to history and whether to allow
1229 
1230 /* static */ bool EffectUI::DoEffect(
1231  const PluginID & ID, const CommandContext &context, unsigned flags )
1232 {
1233  AudacityProject &project = context.project;
1234  auto &tracks = TrackList::Get( project );
1235  auto &trackPanel = TrackPanel::Get( project );
1236  auto &trackFactory = WaveTrackFactory::Get( project );
1237  auto rate = ProjectRate::Get(project).GetRate();
1238  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
1239  auto &commandManager = CommandManager::Get( project );
1240  auto &window = ProjectWindow::Get( project );
1241 
1242  const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID);
1243  if (!plug)
1244  return false;
1245 
1246  EffectType type = plug->GetEffectType();
1247 
1248  // Make sure there's no activity since the effect is about to be applied
1249  // to the project's tracks. Mainly for Apply during RTP, but also used
1250  // for batch commands
1251  if (flags & EffectManager::kConfigured)
1252  {
1253  ProjectAudioManager::Get( project ).Stop();
1254  //Don't Select All if repeating Generator Effect
1255  if (!(flags & EffectManager::kConfigured)) {
1257  }
1258  }
1259 
1260  auto nTracksOriginally = tracks.size();
1261  wxWindow *focus = wxWindow::FindFocus();
1262  wxWindow *parent = nullptr;
1263  if (focus != nullptr) {
1264  parent = focus->GetParent();
1265  }
1266 
1267  bool success = false;
1268  auto cleanup = finally( [&] {
1269 
1270  if (!success) {
1271  // For now, we're limiting realtime preview to a single effect, so
1272  // make sure the menus reflect that fact that one may have just been
1273  // opened.
1274  MenuManager::Get(project).UpdateMenus( false );
1275  }
1276 
1277  } );
1278 
1279  int count = 0;
1280  bool clean = true;
1281  for (auto t : tracks.Selected< const WaveTrack >()) {
1282  if (t->GetEndTime() != 0.0)
1283  clean = false;
1284  count++;
1285  }
1286 
1288 
1289  em.SetSkipStateFlag( false );
1290  if (auto effect = em.GetEffect(ID)) {
1291  success = effect->DoEffect(
1292  rate,
1293  &tracks,
1294  &trackFactory,
1295  selectedRegion,
1296  flags,
1297  &window,
1298  (flags & EffectManager::kConfigured) == 0
1299  ? DialogFactory
1300  : nullptr
1301  );
1302  }
1303  else
1304  success = false;
1305 
1306  if (!success)
1307  return false;
1308 
1309  if (em.GetSkipStateFlag())
1310  flags = flags | EffectManager::kSkipState;
1311 
1312  if (!(flags & EffectManager::kSkipState))
1313  {
1314  auto shortDesc = em.GetCommandName(ID);
1315  auto longDesc = em.GetCommandDescription(ID);
1316  ProjectHistory::Get( project ).PushState(longDesc, shortDesc);
1317  }
1318 
1319  if (!(flags & EffectManager::kDontRepeatLast))
1320  {
1321  // Remember a successful generator, effect, analyzer, or tool Process
1322  auto shortDesc = em.GetCommandName(ID);
1323  /* i18n-hint: %s will be the name of the effect which will be
1324  * repeated if this menu item is chosen */
1325  auto lastEffectDesc = XO("Repeat %s").Format(shortDesc);
1326  auto& menuManager = MenuManager::Get(project);
1327  switch ( type ) {
1328  case EffectTypeGenerate:
1329  commandManager.Modify(wxT("RepeatLastGenerator"), lastEffectDesc);
1330  menuManager.mLastGenerator = ID;
1331  menuManager.mRepeatGeneratorFlags = EffectManager::kConfigured;
1332  break;
1333  case EffectTypeProcess:
1334  commandManager.Modify(wxT("RepeatLastEffect"), lastEffectDesc);
1335  menuManager.mLastEffect = ID;
1336  menuManager.mRepeatEffectFlags = EffectManager::kConfigured;
1337  break;
1338  case EffectTypeAnalyze:
1339  commandManager.Modify(wxT("RepeatLastAnalyzer"), lastEffectDesc);
1340  menuManager.mLastAnalyzer = ID;
1341  menuManager.mLastAnalyzerRegistration = MenuCreator::repeattypeplugin;
1342  menuManager.mRepeatAnalyzerFlags = EffectManager::kConfigured;
1343  break;
1344  case EffectTypeTool:
1345  commandManager.Modify(wxT("RepeatLastTool"), lastEffectDesc);
1346  menuManager.mLastTool = ID;
1347  menuManager.mLastToolRegistration = MenuCreator::repeattypeplugin;
1348  menuManager.mRepeatToolFlags = EffectManager::kConfigured;
1349  if (shortDesc == NYQUIST_PROMPT_NAME) {
1350  menuManager.mRepeatToolFlags = EffectManager::kRepeatNyquistPrompt; //Nyquist Prompt is not configured
1351  }
1352  break;
1353  }
1354  }
1355 
1356  //STM:
1357  //The following automatically re-zooms after sound was generated.
1358  // IMO, it was disorienting, removing to try out without re-fitting
1359  //mchinen:12/14/08 reapplying for generate effects
1360  if (type == EffectTypeGenerate)
1361  {
1362  if (count == 0 || (clean && selectedRegion.t0() == 0.0))
1363  window.DoZoomFit();
1364  // trackPanel->Refresh(false);
1365  }
1366 
1367  // PRL: RedrawProject explicitly because sometimes history push is skipped
1368  window.RedrawProject();
1369 
1370  if (focus != nullptr && focus->GetParent()==parent) {
1371  focus->SetFocus();
1372  }
1373 
1374  // A fix for Bug 63
1375  // New tracks added? Scroll them into view so that user sees them.
1376  // Don't care what track type. An analyser might just have added a
1377  // Label track and we want to see it.
1378  if( tracks.size() > nTracksOriginally ){
1379  // 0.0 is min scroll position, 1.0 is max scroll position.
1380  trackPanel.VerticalScroll( 1.0 );
1381  }
1382  else {
1383  auto pTrack = *tracks.Selected().begin();
1384  if (!pTrack)
1385  pTrack = *tracks.Any().begin();
1386  if (pTrack) {
1387  TrackFocus::Get(project).Set(pTrack);
1388  pTrack->EnsureVisible();
1389  }
1390  }
1391 
1392  return true;
1393 }
1394 
1396 BEGIN_EVENT_TABLE(EffectDialog, wxDialogWrapper)
1397  EVT_BUTTON(wxID_OK, EffectDialog::OnOk)
1399 
1400 EffectDialog::EffectDialog(wxWindow * parent,
1401  const TranslatableString & title,
1402  int type,
1403  int flags,
1404  int additionalButtons)
1405 : wxDialogWrapper(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, flags)
1406 {
1407  mType = type;
1408  mAdditionalButtons = additionalButtons;
1409 }
1410 
1412 {
1413  long buttons = eOkButton;
1414  if ((mType != EffectTypeAnalyze) && (mType != EffectTypeTool))
1415  {
1416  buttons |= eCancelButton;
1417  if (mType == EffectTypeProcess)
1418  {
1419  buttons |= ePreviewButton;
1420  }
1421  }
1422 
1423  ShuttleGui S(this, eIsCreating);
1424 
1425  S.SetBorder(5);
1426  S.StartVerticalLay(true);
1427  {
1429  S.AddStandardButtons(buttons|mAdditionalButtons);
1430  }
1431  S.EndVerticalLay();
1432 
1433  Layout();
1434  Fit();
1435  SetMinSize(GetSize());
1436  Center();
1437 }
1438 
1443 {
1444  return;
1445 }
1446 
1448 {
1451 
1452  return true;
1453 }
1454 
1456 {
1459 
1460  return true;
1461 }
1462 
1464 {
1465  return true;
1466 }
1467 
1468 void EffectDialog::OnPreview(wxCommandEvent & WXUNUSED(evt))
1469 {
1470  return;
1471 }
1472 
1473 void EffectDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
1474 {
1475  // On wxGTK (wx2.8.12), the default action is still executed even if
1476  // the button is disabled. This appears to affect all wxDialogs, not
1477  // just our Effects dialogs. So, this is a only temporary workaround
1478  // for legacy effects that disable the OK button. Hopefully this has
1479  // been corrected in wx3.
1480  if (FindWindow(wxID_OK)->IsEnabled() && Validate() && TransferDataFromWindow())
1481  {
1482  EndModal(wxID_OK);
1483  }
1484 
1485  return;
1486 }
EffectUIClientInterface
EffectUIClientInterface is an abstract base class to populate a UI and validate UI values....
Definition: EffectInterface.h:251
EffectManager::GetSkipStateFlag
bool GetSkipStateFlag()
Definition: EffectManager.cpp:219
EVT_BUTTON
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
EffectUIHost::ShowModal
int ShowModal() override
Definition: EffectUI.cpp:214
EffectDialog::mAdditionalButtons
int mAdditionalButtons
Definition: EffectUI.h:184
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
EffectUIHost::mStopBM
wxBitmap mStopBM
Definition: EffectUI.h:118
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
EffectUIHost::mIsBatch
bool mIsBatch
Definition: EffectUI.h:103
EffectUIHost::mDisableTransport
bool mDisableTransport
Definition: EffectUI.h:123
label
TranslatableString label
Definition: TagsEditor.cpp:163
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:39
EffectUIHost::mClient
EffectUIClientInterface & mClient
Definition: EffectUI.h:97
TranslatableString::empty
bool empty() const
Definition: TranslatableString.h:72
WaveTrackFactory::Get
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:2799
EffectDialog::OnPreview
virtual void OnPreview(wxCommandEvent &evt)
Definition: EffectUI.cpp:1468
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:75
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:56
EffectUIHost::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: EffectUI.cpp:205
kDeletePresetID
static const int kDeletePresetID
Definition: EffectUI.cpp:131
kImportID
static const int kImportID
Definition: EffectUI.cpp:117
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:423
ProjectAudioManager::Get
static ProjectAudioManager & Get(AudacityProject &project)
Definition: ProjectAudioManager.cpp:55
S
#define S(N)
Definition: ToChars.cpp:64
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Definition: AudacityMessageBox.cpp:17
RealtimeEffectManager::RealtimeSuspendOne
void RealtimeSuspendOne(EffectProcessor &effect)
Definition: RealtimeEffectManager.cpp:170
eIsGettingFromDialog
@ eIsGettingFromDialog
Definition: ShuttleGui.h:40
ComponentInterfaceSymbol::Translation
const wxString Translation() const
Definition: ComponentInterfaceSymbol.h:58
EffectHostInterface
EffectHostInterface is a decorator of a EffectUIClientInterface. It adds virtual (abstract) functions...
Definition: EffectHostInterface.h:32
Effect.h
EffectDialog::Init
void Init()
Definition: EffectUI.cpp:1411
kRewindID
static const int kRewindID
Definition: EffectUI.cpp:126
entries
static ProjectFileIORegistry::AttributeReaderEntries entries
Definition: ProjectSettings.cpp:211
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:71
SelectedRegion::t1
double t1() const
Definition: SelectedRegion.h:95
Effect::TransferDataToWindow
virtual bool TransferDataToWindow()
Definition: Effect.cpp:1684
eHelpButton
@ eHelpButton
Definition: ShuttleGui.h:604
Project.h
ePreviewButton
@ ePreviewButton
Definition: ShuttleGui.h:605
EffectUIHost::DoCancel
void DoCancel()
Definition: EffectUI.cpp:585
Effect::SupportsRealtime
bool SupportsRealtime() override
Whether the effect supports realtime previewing (while audio is playing).
Definition: Effect.cpp:212
Track::EnsureVisible
void EnsureVisible(bool modifyState=false)
Definition: Track.cpp:95
wxPanelWrapper
Definition: wxPanelWrapper.h:41
ProjectRate::Get
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
Effect
An Effect object is at once host and client: it is self-hosting.
Definition: Effect.h:77
EffectTypeGenerate
@ EffectTypeGenerate
Definition: EffectInterface.h:55
wxPanelWrapper::SetLabel
void SetLabel(const TranslatableString &label)
Definition: wxPanelWrapper.cpp:46
kPlaybackID
static const int kPlaybackID
Definition: EffectUI.cpp:128
EffectUIHost::OnPlayback
void OnPlayback(AudioIOEvent)
Definition: EffectUI.cpp:839
EffectUIClientInterface::ImportPresets
virtual void ImportPresets()=0
EffectUIHost::OnClose
void OnClose(wxCloseEvent &evt)
Definition: EffectUI.cpp:502
Format
Abstract base class used in importing a file.
kFactoryPresetsID
static const int kFactoryPresetsID
Definition: EffectUI.cpp:132
TranslatableString::Inaudible
static const TranslatableString Inaudible
A special string value that will have no screen reader pronunciation.
Definition: TranslatableString.h:34
EffectUIHost::OnApply
void OnApply(wxCommandEvent &evt)
Definition: EffectUI.cpp:520
kCaptureID
static const int kCaptureID
Definition: EffectUI.cpp:129
Effect::LoadUserPreset
bool LoadUserPreset(const RegistryPath &name) override
Change settings to a user-named preset.
Definition: Effect.cpp:530
EffectUIHost::OnSaveAs
void OnSaveAs(wxCommandEvent &evt)
Definition: EffectUI.cpp:925
wxWidgetsWindowPlacement.h
EffectManager::kConfigured
@ kConfigured
Definition: EffectManager.h:49
EffectManager::kDontRepeatLast
@ kDontRepeatLast
Definition: EffectManager.h:53
EffectUIHost::Initialize
bool Initialize()
Definition: EffectUI.cpp:381
PluginSettings::GetConfigSubgroups
bool GetConfigSubgroups(EffectDefinitionInterface &ident, PluginSettings::ConfigurationType type, const RegistryPath &group, RegistryPaths &subgroups)
Definition: ConfigInterface.cpp:23
EffectManager::GetCommandName
TranslatableString GetCommandName(const PluginID &ID)
Definition: EffectManager.cpp:101
EffectUIHost::OnDebug
void OnDebug(wxCommandEvent &evt)
Definition: EffectUI.cpp:616
DefaultPlayOptions
AudioIOStartStreamOptions DefaultPlayOptions(AudacityProject &project, bool newDefault)
Definition: ProjectAudioManager.cpp:1144
EffectUIHost::mMenuBtn
wxButton * mMenuBtn
Definition: EffectUI.h:107
TrackPanel::Get
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:227
XO
#define XO(s)
Definition: Internat.h:31
EffectUIHost::OnEnable
void OnEnable(wxCommandEvent &evt)
Definition: EffectUI.cpp:726
EffectUIHost::OnCancel
void OnCancel(wxCommandEvent &evt)
Definition: EffectUI.cpp:597
SelectedRegion::setTimes
bool setTimes(double t0, double t1)
Definition: SelectedRegion.h:139
kPlayID
static const int kPlayID
Definition: EffectUI.cpp:125
NYQUISTEFFECTS_FAMILY
#define NYQUISTEFFECTS_FAMILY
Definition: Effect.h:65
EffectUIHost::OnFFwd
void OnFFwd(wxCommandEvent &evt)
Definition: EffectUI.cpp:816
eDebugButton
@ eDebugButton
Definition: ShuttleGui.h:606
EffectDefinitionInterface::EnablesDebug
virtual bool EnablesDebug()
Whether the effect dialog should have a Debug button; default, always false.
Definition: EffectInterface.cpp:39
EffectDialog::TransferDataToWindow
bool TransferDataToWindow() override
Definition: EffectUI.cpp:1447
Effect::IsBatchProcessing
virtual bool IsBatchProcessing()
Definition: Effect.cpp:960
kUserPresetsID
static const int kUserPresetsID
Definition: EffectUI.cpp:130
ProjectWindow::Get
static ProjectWindow & Get(AudacityProject &project)
Definition: ProjectWindow.cpp:525
FindProjectFromWindow
AudacityProject * FindProjectFromWindow(wxWindow *pWindow)
Definition: ProjectWindowBase.cpp:44
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
EffectManager::Get
static EffectManager & Get()
Definition: EffectManager.cpp:42
Effect::GetUserPresetsGroup
RegistryPath GetUserPresetsGroup(const RegistryPath &name) override
Definition: Effect.cpp:809
EffectUIHost::mInitialized
bool mInitialized
Definition: EffectUI.h:100
EffectUIHost::OnOptions
void OnOptions(wxCommandEvent &evt)
Definition: EffectUI.cpp:1021
Effect::SaveUserPreset
bool SaveUserPreset(const RegistryPath &name) override
Save current settings as a user-named preset.
Definition: Effect.cpp:547
EffectUIHost::Resume
void Resume()
Definition: EffectUI.cpp:711
HelpSystem::ShowHelp
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:237
MenuCreator::repeattypeplugin
@ repeattypeplugin
Definition: Menus.h:61
eIsSettingToDialog
@ eIsSettingToDialog
Definition: ShuttleGui.h:41
AudacityMessageDialog
Wrap wxMessageDialog so that caption IS translatable.
Definition: wxPanelWrapper.h:215
WaveTracksSelectedFlag
const ReservedCommandFlag & WaveTracksSelectedFlag()
Definition: CommonCommandFlags.cpp:165
Effect::TransferDataFromWindow
virtual bool TransferDataFromWindow()
Definition: Effect.cpp:1689
eApplyButton
@ eApplyButton
Definition: ShuttleGui.h:609
EffectUIHost::mCapturing
bool mCapturing
Definition: EffectUI.h:125
wxWidgetsWindowPlacement
Window placement information for wxWidgetsBasicUI can be constructed from a wxWindow pointer.
Definition: wxWidgetsWindowPlacement.h:22
EffectManager::SetSkipStateFlag
void SetSkipStateFlag(bool flag)
Definition: EffectManager.cpp:214
kDummyID
static const int kDummyID
Definition: EffectUI.cpp:115
EffectUIHost::mPlayBtn
wxButton * mPlayBtn
Definition: EffectUI.h:108
PlayMode::normalPlay
@ normalPlay
EffectUIHost::OnImport
void OnImport(wxCommandEvent &evt)
Definition: EffectUI.cpp:1003
kFFwdID
static const int kFFwdID
Definition: EffectUI.cpp:127
kExportID
static const int kExportID
Definition: EffectUI.cpp:118
kOptionsID
static const int kOptionsID
Definition: EffectUI.cpp:120
EffectUI.h
EffectUIHost::mEnableCb
wxCheckBox * mEnableCb
Definition: EffectUI.h:111
EffectUIHost::mFFwdBtn
wxButton * mFFwdBtn
Definition: EffectUI.h:110
EffectDialog::Validate
bool Validate() override
Definition: EffectUI.cpp:1463
EffectPanel::~EffectPanel
virtual ~EffectPanel()
Definition: EffectUI.cpp:51
RealtimeEffectManager::RealtimeAddEffect
void RealtimeAddEffect(EffectProcessor &effect)
Definition: RealtimeEffectManager.cpp:59
eDebugID
@ eDebugID
Definition: ShuttleGui.h:619
EffectUIClientInterface::ShowOptions
virtual void ShowOptions()=0
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:215
XXO
#define XXO(s)
Definition: Internat.h:44
eCancelButton
@ eCancelButton
Definition: ShuttleGui.h:601
EffectManager
EffectManager is the class that handles effects and effect categories.
Definition: EffectManager.h:42
MenuManager::UpdateMenus
void UpdateMenus(bool checkActive=true)
Definition: Menus.cpp:637
factory
static RegisteredToolbarFactory factory
Definition: ControlToolBar.cpp:820
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:34
RealtimeEffectManager.h
EffectUIHost::mStopDisabledBM
wxBitmap mStopDisabledBM
Definition: EffectUI.h:119
EffectUIHost::mDismissed
bool mDismissed
Definition: EffectUI.h:130
EffectManager::GetEffect
Effect * GetEffect(const PluginID &ID)
Definition: EffectManager.cpp:735
Effect::GetFactoryPresets
RegistryPaths GetFactoryPresets() override
Report names of factory presets.
Definition: Effect.cpp:562
EffectUIHost::mParent
wxWindow * mParent
Definition: EffectUI.h:95
EffectUIHost::InitializeRealtime
void InitializeRealtime()
Definition: EffectUI.cpp:1159
PluginManager.h
EffectUIHost::mProject
AudacityProject * mProject
Definition: EffectUI.h:94
EffectUIHost::mEffect
Effect & mEffect
Definition: EffectUI.h:96
RealtimeEffectManager::RealtimeRemoveEffect
void RealtimeRemoveEffect(EffectProcessor &effect)
Definition: RealtimeEffectManager.cpp:82
NYQUIST_PROMPT_NAME
#define NYQUIST_PROMPT_NAME
Definition: PluginManager.h:343
EffectUIHost::mRegion
SelectedRegion mRegion
Definition: EffectUI.h:127
Effect::LoadFactoryDefaults
bool LoadFactoryDefaults() override
Change settings back to "factory default".
Definition: Effect.cpp:582
EffectPanel::AcceptsFocus
bool AcceptsFocus() const override
Definition: EffectUI.cpp:59
EffectUIHost::OnPlay
void OnPlay(wxCommandEvent &evt)
Definition: EffectUI.cpp:743
kDeletePresetDummyID
static const int kDeletePresetDummyID
Definition: EffectUI.cpp:122
EffectPanel::SetAccept
void SetAccept(bool accept)
Definition: EffectUI.cpp:73
Effect::GetType
EffectType GetType() override
Type determines how it behaves.
Definition: Effect.cpp:110
PluginID
wxString PluginID
Definition: EffectManager.h:31
EffectDialog::PopulateOrExchange
virtual void PopulateOrExchange(ShuttleGui &S)
Definition: EffectUI.cpp:1442
EffectPanel::mAcceptsFocus
bool mAcceptsFocus
Definition: EffectUI.cpp:79
SelectUtilities::SelectAllIfNone
void SelectAllIfNone(AudacityProject &project)
Definition: SelectUtilities.cpp:92
name
const TranslatableString name
Definition: Distortion.cpp:98
RealtimeEffectManager::RealtimeResumeOne
void RealtimeResumeOne(EffectProcessor &effect)
Definition: RealtimeEffectManager.cpp:199
EVT_MENU
EVT_MENU(OnSetPlayRegionToSelectionID, AdornedRulerPanel::OnSetPlayRegionToSelection) EVT_COMMAND(OnTogglePinnedStateID
EffectTypeTool
@ EffectTypeTool
Definition: EffectInterface.h:58
EffectUIHost::mPlaying
bool mPlaying
Definition: EffectUI.h:124
kEnableID
static const int kEnableID
Definition: EffectUI.cpp:124
EffectDialog
Definition: EffectUI.h:162
EffectPanel
Definition: EffectUI.cpp:39
EffectUIHost::mEnabled
bool mEnabled
Definition: EffectUI.h:121
TrackFocus::Get
Track * Get()
Definition: TrackPanelAx.cpp:760
EffectUIHost::OnDeletePreset
void OnDeletePreset(wxCommandEvent &evt)
Definition: EffectUI.cpp:905
EffectUIHost::OnRewind
void OnRewind(wxCommandEvent &evt)
Definition: EffectUI.cpp:794
PluginManager::GetPlugin
const PluginDescriptor * GetPlugin(const PluginID &ID) const
Definition: PluginManager.cpp:1335
PluginDescriptor
Definition: PluginManager.h:45
ProjectRate::GetRate
double GetRate() const
Definition: ProjectRate.cpp:53
ProjectAudioManager::Stop
void Stop(bool stopStream=true)
Definition: ProjectAudioManager.cpp:499
ViewInfo.h
EffectUIHost::OnInitDialog
void OnInitDialog(wxInitDialogEvent &evt)
Definition: EffectUI.cpp:467
EffectUIHost::OnPaint
void OnPaint(wxPaintEvent &evt)
Definition: EffectUI.cpp:495
EffectUIHost::mApplyBtn
wxButton * mApplyBtn
Definition: EffectUI.h:105
Effect::GetCurrentSettingsGroup
RegistryPath GetCurrentSettingsGroup() override
Definition: Effect.cpp:820
EffectUIHost::OnUserPreset
void OnUserPreset(wxCommandEvent &evt)
Definition: EffectUI.cpp:889
EffectUIHost::OnHelp
void OnHelp(wxCommandEvent &evt)
Definition: EffectUI.cpp:603
Effect::Preview
virtual void Preview(bool dryOnly)
Definition: Effect.cpp:2053
EffectManager::kRepeatNyquistPrompt
@ kRepeatNyquistPrompt
Definition: EffectManager.h:57
AudioIOEvent::pProject
AudacityProject * pProject
Definition: AudioIO.h:60
EffectUIHost::mIsGUI
bool mIsGUI
Definition: EffectUI.h:102
Effect::GetVendor
VendorSymbol GetVendor() override
Definition: Effect.cpp:140
ProjectHistory::PushState
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
Definition: ProjectHistory.cpp:90
EffectUIHost::mUserPresets
RegistryPaths mUserPresets
Definition: EffectUI.h:99
wxDialogWrapper
Definition: wxPanelWrapper.h:81
wxPanelWrapper::SetName
void SetName()
Definition: wxPanelWrapper.cpp:61
SelectedRegion::t0
double t0() const
Definition: SelectedRegion.h:94
EffectUIHost::mPlayBM
wxBitmap mPlayBM
Definition: EffectUI.h:116
EffectUIHost::BuildButtonBar
wxPanel * BuildButtonBar(wxWindow *parent)
Definition: EffectUI.cpp:243
PluginManager::Get
static PluginManager & Get()
Definition: PluginManager.cpp:582
RealtimeEffectManager::Get
static RealtimeEffectManager & Get(AudacityProject &project)
Definition: RealtimeEffectManager.cpp:30
EffectUIHost::OnMenu
void OnMenu(wxCommandEvent &evt)
Definition: EffectUI.cpp:621
PluginDescriptor::GetEffectType
EffectType GetEffectType() const
Definition: PluginManager.cpp:191
title
static const auto title
Definition: NoUpdatesAvailableDialog.cpp:22
EffectUIHost::OnDefaults
void OnDefaults(wxCommandEvent &evt)
Definition: EffectUI.cpp:1028
eOkButton
@ eOkButton
Definition: ShuttleGui.h:600
Effect::GetFamily
EffectFamilySymbol GetFamily() override
Report identifier and user-visible name of the effect protocol.
Definition: Effect.cpp:170
MenuManager::ReportIfActionNotAllowed
bool ReportIfActionNotAllowed(const TranslatableString &Name, CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:699
EffectUIClientInterface::PopulateUI
virtual bool PopulateUI(ShuttleGui &S)=0
Adds controls to a panel that is given as the parent window of S
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:377
AudioIOEvent::on
bool on
Definition: AudioIO.h:66
EffectUIHost::OnCapture
void OnCapture(AudioIOEvent)
Definition: EffectUI.cpp:867
EffectDefinitionInterface::HelpPage
virtual FilePath HelpPage()
Fully qualified local help file name, default is empty.
Definition: EffectInterface.cpp:49
kUserPresetsDummyID
static const int kUserPresetsDummyID
Definition: EffectUI.cpp:121
EffectUIHost::OnFactoryPreset
void OnFactoryPreset(wxCommandEvent &evt)
Definition: EffectUI.cpp:898
EffectUIHost::mPlayDisabledBM
wxBitmap mPlayDisabledBM
Definition: EffectUI.h:117
_
#define _(s)
Definition: Internat.h:75
EffectUIHost::CreateBitmap
wxBitmap CreateBitmap(const char *const xpm[], bool up, bool pusher)
Definition: EffectUI.cpp:1035
PluginManager::GetID
static PluginID GetID(ModuleInterface *module)
Definition: PluginManager.cpp:1443
Effect::GetDescription
TranslatableString GetDescription() override
Definition: Effect.cpp:160
EffectTypeAnalyze
@ EffectTypeAnalyze
Definition: EffectInterface.h:57
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
EffectUIClientInterface::CloseUI
virtual bool CloseUI()=0
eCloseButton
@ eCloseButton
Definition: ShuttleGui.h:610
TimeSelectedFlag
const ReservedCommandFlag & TimeSelectedFlag()
Definition: CommonCommandFlags.cpp:160
EffectUIHost::mRewindBtn
wxButton * mRewindBtn
Definition: EffectUI.h:109
kDefaultsID
static const int kDefaultsID
Definition: EffectUI.cpp:119
EffectUIHost::OnExport
void OnExport(wxCommandEvent &evt)
Definition: EffectUI.cpp:1012
MenuManager::Get
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:70
EffectUIHost::~EffectUIHost
virtual ~EffectUIHost()
Definition: EffectUI.cpp:191
kMenuID
static const int kMenuID
Definition: EffectUI.cpp:123
EffectPanel::AcceptsFocusFromKeyboard
bool AcceptsFocusFromKeyboard() const override
Definition: EffectUI.cpp:65
EffectUIHost
Definition: EffectUI.h:39
AudioIOEvent::type
enum AudioIOEvent::Type type
GetID
static PluginID GetID(Effect &effect)
Definition: EffectUI.cpp:27
EffectPanel::EffectPanel
EffectPanel(wxWindow *parent)
Definition: EffectUI.cpp:41
EffectManager::kSkipState
@ kSkipState
Definition: EffectManager.h:51
ProjectRate.h
an object holding per-project preferred sample rate
BasicMenu.h
Abstractions of menus and their items.
EffectDialog::mType
int mType
Definition: EffectUI.h:183
EffectUI::DoEffect
AUDACITY_DLL_API bool DoEffect(const PluginID &ID, const CommandContext &context, unsigned flags)
'Repeat Last Effect'.
Definition: EffectUI.cpp:1230
EffectManager::GetCommandDescription
TranslatableString GetCommandDescription(const PluginID &ID)
Definition: EffectManager.cpp:128
RTL_WORKAROUND
#define RTL_WORKAROUND(pWnd)
Definition: GUISettings.h:16
Effect::GetDefinition
EffectDefinitionInterface & GetDefinition() override
Definition: Effect.cpp:759
EffectUIClientInterface::CanExportPresets
virtual bool CanExportPresets()=0
NotifyingSelectedRegion::isPoint
bool isPoint() const
Definition: ViewInfo.h:39
AudioIOEvent
Definition: AudioIO.h:59
TranslatableString::Translation
wxString Translation() const
Definition: TranslatableString.h:79
EffectUI::DialogFactory
AUDACITY_DLL_API wxDialog * DialogFactory(wxWindow &parent, EffectHostInterface &host, EffectUIClientInterface &client)
Definition: EffectUI.cpp:1190
EffectUIHost::mPlayPos
double mPlayPos
Definition: EffectUI.h:128
ComponentInterface::GetName
TranslatableString GetName()
Definition: PluginManager.cpp:1838
EffectUIHost::mPlayToggleBtn
wxButton * mPlayToggleBtn
Definition: EffectUI.h:114
CommandManager::Get
static CommandManager & Get(AudacityProject &project)
Definition: CommandManager.cpp:207
EffectUIHost::mCloseBtn
wxButton * mCloseBtn
Definition: EffectUI.h:106
Destroy_ptr
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Definition: MemoryX.h:162
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:140
EffectUIClientInterface::IsGraphicalUI
virtual bool IsGraphicalUI()=0
PluginSettings::RemoveConfigSubgroup
bool RemoveConfigSubgroup(EffectDefinitionInterface &ident, PluginSettings::ConfigurationType type, const RegistryPath &group)
Definition: ConfigInterface.cpp:53
EffectType
EffectType
Definition: EffectInterface.h:52
safenew
#define safenew
Definition: MemoryX.h:10
EffectManager.h
EVT_MENU_RANGE
EVT_MENU_RANGE(FileHistory::ID_RECENT_FIRST, FileHistory::ID_RECENT_LAST, AudacityApp::OnMRUFile) bool AudacityApp
Definition: AudacityApp.cpp:865
EffectUIClientInterface::ExportPresets
virtual void ExportPresets()=0
EffectDialog::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: EffectUI.cpp:1455
EffectUIClientInterface::HasOptions
virtual bool HasOptions()=0
EffectUIHost::UpdateControls
void UpdateControls()
Definition: EffectUI.cpp:1068
EffectUIHost::mNeedsResume
bool mNeedsResume
Definition: EffectUI.h:131
CommandContext::project
AudacityProject & project
Definition: CommandContext.h:64
BasicMenu::Handle::Popup
void Popup(const BasicUI::WindowPlacement &window, const Point &pos={})
Display the menu at pos, invoke at most one action, then hide it.
Definition: BasicMenu.cpp:207
EffectUIHost::CleanupRealtime
void CleanupRealtime()
Definition: EffectUI.cpp:1180
EffectUIHost::OnErase
void OnErase(wxEraseEvent &evt)
Definition: EffectUI.cpp:490
END_EVENT_TABLE
END_EVENT_TABLE()
kSaveAsID
static const int kSaveAsID
Definition: EffectUI.cpp:116
EffectUIHost::LoadUserPresets
void LoadUserPresets()
Definition: EffectUI.cpp:1147
Effect::GetVersion
wxString GetVersion() override
Definition: Effect.cpp:150
EffectUIHost::TransferDataToWindow
bool TransferDataToWindow() override
Definition: EffectUI.cpp:200
Identifier::empty
bool empty() const
Definition: Identifier.h:61
Observer::Publisher::Subscribe
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
EffectUIClientInterface::ValidateUI
virtual bool ValidateUI()=0
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
EffectDialog::OnOk
virtual void OnOk(wxCommandEvent &evt)
Definition: EffectUI.cpp:1473
PluginSettings::Private
@ Private
Definition: PluginInterface.h:56
EffectUIHost::mSupportsRealtime
bool mSupportsRealtime
Definition: EffectUI.h:101
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
Effect::LoadFactoryPreset
bool LoadFactoryPreset(int id) override
Change settings to the preset whose name is GetFactoryPresets()[id]
Definition: Effect.cpp:572
BasicMenu::Handle
Definition: BasicMenu.h:26
EffectDefinitionInterface::ManualPage
virtual ManualPageID ManualPage()
Name of a page in the Audacity alpha manual, default is empty.
Definition: EffectInterface.cpp:44
SelectedRegion
Defines a selected portion of a project.
Definition: SelectedRegion.h:38