1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-11 00:53:46 +02:00

Bug 368: VST plugins now have a dialog that gives a list of plugine to choose from.

This commit is contained in:
james.k.crook@gmail.com
2013-08-24 15:38:26 +00:00
parent 71def3fad2
commit 4c2544874d
4 changed files with 381 additions and 32 deletions

View File

@@ -41,3 +41,167 @@ static const char * empty_9x16_xpm[] = {
".........",
".........",
"........."};
/* XPM */
static char * unchecked_xpm[] = {
"15 15 56 1",
" c None",
". c #FFFFFF",
"+ c #8E8F8F",
"@ c #F4F4F4",
"# c #AEB3B9",
"$ c #AFB4BA",
"% c #B4B9BD",
"& c #BBBEC1",
"* c #CBCFD5",
"= c #D0D3D8",
"- c #D5D8DC",
"; c #DBDDDF",
"> c #C1C3C5",
", c #CDD1D6",
"' c #D2D5DA",
") c #D8DBDE",
"! c #DDDFE1",
"~ c #E2E3E4",
"{ c #C6C7C8",
"] c #CDD1D7",
"^ c #D0D4D9",
"/ c #D4D7DB",
"( c #E1E2E3",
"_ c #E5E6E6",
": c #E8E8E8",
"< c #CCCDCD",
"[ c #B2B7BC",
"} c #DADCDF",
"| c #E0E1E3",
"1 c #ECECEC",
"2 c #EDEDED",
"3 c #D4D5D6",
"4 c #B8BBBF",
"5 c #E4E5E5",
"6 c #EAEAEA",
"7 c #EFEFEF",
"8 c #F2F2F2",
"9 c #DCDDDE",
"0 c #BCBFC2",
"a c #E3E4E5",
"b c #E9E9E9",
"c c #F5F5F5",
"d c #E1E2E2",
"e c #C2C4C6",
"f c #F0F0F0",
"g c #F6F6F6",
"h c #E6E6E6",
"i c #CACBCC",
"j c #D4D4D5",
"k c #DBDBDC",
"l c #E0E1E1",
"m c #E6E7E7",
"n c #EAEBEB",
"o c #EBECEC",
"p c #EBEBEC",
"q c #E9E9EA",
"...............",
".+++++++++++++.",
".+@@@@@@@@@@@+.",
".+@######$%&@+.",
".+@#****=-;>@+.",
".+@#**,')!~{@+.",
".+@#]^/;(_:<@+.",
".+@[-}|:1223@+.",
".+@4!5678889@+.",
".+@0ab28@c@d@+.",
".+@eb2f@gggh@+.",
".+@ijklmnopq@+.",
".+@@@@@@@@@@@+.",
".+++++++++++++.",
"..............."};
/* XPM */
static char * checked_xpm[] = {
"15 15 70 1",
" c #FFFFFF",
". c #8E8F8F",
"+ c #F4F4F4",
"@ c #F8F8F8",
"# c #F9F9F9",
"$ c #F6F6F6",
"% c #AEB3B9",
"& c #C9CCD0",
"* c #76DB7E",
"= c #45CE4F",
"- c #DCDFE4",
"; c #F5F5F5",
"> c #CBCFD5",
", c #C9D3D2",
"' c #EBEFEF",
") c #2EAF37",
"! c #289730",
"~ c #9CE5A2",
"{ c #CDD1D6",
"] c #E0E2E6",
"^ c #90E196",
"/ c #3DB351",
"( c #E4EAE5",
"_ c #ADB5B7",
": c #D5D9DD",
"< c #DFE2E5",
"[ c #D5D8DC",
"} c #EFF5F1",
"| c #30B93A",
"1 c #289B31",
"2 c #A1E6A6",
"3 c #DBDCDC",
"4 c #C5C9CD",
"5 c #B3EAB7",
"6 c #87D693",
"7 c #E9F1EA",
"8 c #A0E5A5",
"9 c #299E32",
"0 c #33C23D",
"a c #D5D5D6",
"b c #CDF2D0",
"c c #3ACB45",
"d c #299A33",
"e c #BFE9C6",
"f c #33C43E",
"g c #2A9F32",
"h c #9BE4A0",
"i c #F5F7F5",
"j c #DCDDDE",
"k c #C8D4CC",
"l c #D0EFD5",
"m c #299C31",
"n c #32BD3C",
"o c #F7FAF9",
"p c #DFE4E0",
"q c #C6C8CA",
"r c #E5F0E9",
"s c #62D56A",
"t c #2BA233",
"u c #93E299",
"v c #F7F9F8",
"w c #E5E7E5",
"x c #CACBCC",
"y c #D9DBDA",
"z c #DEE3E8",
"A c #76C38B",
"B c #F2F3F6",
"C c #ECEDED",
"D c #EBEBEC",
"E c #E9E9EA",
" ",
" ............. ",
" .+++++++@#$+. ",
" .+%%%%%&*=-;. ",
" .+%>>>,')!~$. ",
" .+%>>{]^!/(+. ",
" .+_:<[}|123+. ",
" .+4567890@a+. ",
" .+bcdefghij+. ",
" .+klm9gno+p+. ",
" .+qrs9tuv$w+. ",
" .+xyzsABCDE+. ",
" .+++;#@;++++. ",
" ............. ",
" "};

View File

@@ -185,6 +185,7 @@ void PluginManager::PurgeType(const wxString & type)
path.Printf(wxT("/%s"), type.c_str());
SetDirty();
mConfig->DeleteGroup(path);
}

View File

@@ -32,6 +32,8 @@
#include <wx/stattext.h>
#include <wx/stopwatch.h>
#include <wx/utils.h>
#include <wx/dcclient.h>
#include <wx/imaglist.h>
#if defined(__WXMAC__)
#include <dlfcn.h>
@@ -57,6 +59,8 @@
#include "../../xml/XMLFileReader.h"
#include "../../xml/XMLWriter.h"
#include "../EffectManager.h"
#include "../../Theme.h"
#include "../images/Arrow.xpm"
#include "VSTEffect.h"
@@ -73,7 +77,7 @@ void RegisterVSTEffects()
pm.Open();
bool bScanRequired = false;
if (gPrefs->Read(wxT("/VST/Rescan"), (long)true) != false) {
if ( bScanRequired || gPrefs->Read(wxT("/VST/Rescan"), (long)true) != false) {
pm.PurgeType(VSTPLUGINTYPE);
gPrefs->Write(wxT("/VST/Rescan"), false);
gPrefs->Flush();
@@ -81,14 +85,12 @@ void RegisterVSTEffects()
}
if (!pm.HasType(VSTPLUGINTYPE)) {
// rescan.
pm.Close();
if( bScanRequired)
VSTEffect::Scan();
pm.Open();
}
EffectManager & em = EffectManager::Get();
wxString path = pm.GetFirstPlugin(VSTPLUGINTYPE);
@@ -107,6 +109,164 @@ void RegisterVSTEffects()
pm.Close();
}
class PluginRegistrationDialog:public wxDialog {
public:
// constructors and destructors
PluginRegistrationDialog(wxWindow * parent, const wxArrayString & files);
virtual ~PluginRegistrationDialog();
public:
void Populate();
void PopulateOrExchange( ShuttleGui & S );
void OnApply(wxCommandEvent & event);
void OnCancel(wxCommandEvent & event);
void OnToggleState( wxListEvent & event );
wxButton *mOK;
wxButton *mCancel;
wxListCtrl *mPlugins;
wxArrayString mFiles;
wxArrayInt miState;
// wxListCtrl *mList;
// BatchCommands mBatchCommands;
bool mAbort;
DECLARE_EVENT_TABLE()
};
#define PluginListID 7001
BEGIN_EVENT_TABLE(PluginRegistrationDialog, wxDialog)
EVT_BUTTON(wxID_OK, PluginRegistrationDialog::OnApply)
EVT_BUTTON(wxID_CANCEL, PluginRegistrationDialog::OnCancel)
EVT_LIST_ITEM_SELECTED( wxID_ANY, PluginRegistrationDialog::OnToggleState )
END_EVENT_TABLE()
PluginRegistrationDialog::PluginRegistrationDialog(wxWindow * parent, const wxArrayString & files):
mFiles( files ),
wxDialog(parent, wxID_ANY, _("Install VST Plugins"),
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
SetLabel(_("Install VST Plugins")); // Provide visual label
SetName(_("Install VST Plugins")); // Provide audible label
Populate();
mAbort = false;
}
PluginRegistrationDialog::~PluginRegistrationDialog()
{
}
void PluginRegistrationDialog::Populate()
{
//------------------------- Main section --------------------
ShuttleGui S(this, eIsCreating);
PopulateOrExchange(S);
// ----------------------- End of main section --------------
}
/// Defines the dialog and does data exchange with it.
void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S)
{
wxImageList * pImageList = new wxImageList( 16, 16 );
#define SHOW_UNCHECKED (0)
#define SHOW_CHECKED (1)
#define SHOW_ARROW (2)
pImageList->Add(wxIcon(unchecked_xpm));
pImageList->Add(wxIcon(checked_xpm));
pImageList->Add(wxIcon(arrow_xpm));
S.StartVerticalLay(true);
{
/*i18n-hint: The dialog shows a list of plugins with check-boxes
beside each one.*/
S.StartStatic(_("&Select Plugins to Install"), true);
{
S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES );
mPlugins = S.Id(PluginListID).AddListControlReportMode();
mPlugins->AssignImageList( pImageList, wxIMAGE_LIST_SMALL );
mPlugins->InsertColumn(0, _("Plugin File"), wxLIST_FORMAT_LEFT);
}
S.EndStatic();
S.StartHorizontalLay(wxALIGN_RIGHT, false);
{
S.SetBorder(10);
S.Id(wxID_CANCEL).AddButton(_("&Cancel"));
S.Id(wxID_OK).AddButton(_("OK"))->SetDefault();
}
S.EndHorizontalLay();
}
S.EndVerticalLay();
wxClientDC dc( this );
int iLen = 100;
wxSize siz;
for (int i = 0; i < (int)mFiles.GetCount(); i++) {
miState.Add( SHOW_CHECKED ); // 1 is selected.
mPlugins->InsertItem(i, mFiles[i], SHOW_CHECKED);
siz = dc.GetTextExtent( mFiles[i] );
if( siz.GetWidth() > iLen )
iLen = siz.GetWidth();
}
mPlugins->SetColumnWidth(0, iLen);
mPlugins->SetSizeHints( iLen, 200 );
Layout();
Fit();
SetSizeHints(GetSize());
Center();
}
void PluginRegistrationDialog::OnToggleState(wxListEvent & event)
{
int i = event.GetIndex();
miState[ i ] = (miState[ i ]==SHOW_CHECKED) ? SHOW_UNCHECKED : SHOW_CHECKED; // Toggle it.
mPlugins->SetItemState( i, 0 ,wxLIST_STATE_SELECTED);
mPlugins->SetItemImage( i, miState[i] );
}
void PluginRegistrationDialog::OnApply(wxCommandEvent & event)
{
size_t cnt = mFiles.GetCount();
for (size_t i = 0; i < cnt; i++) {
wxString file = mFiles[i];
#if 0
int status = progress->Update(wxLongLong(i),
wxLongLong(cnt),
wxString::Format(_("Checking %s"), file.c_str()));
if (status != eProgressSuccess) {
break;
}
#endif
mPlugins->EnsureVisible( i );
if( miState[ i ] == SHOW_CHECKED )
{
mPlugins->SetItemImage( i, SHOW_ARROW );
VSTEffect::ScanOnePlugin( file );
mPlugins->SetItemImage( i, SHOW_CHECKED );
}
}
EndModal( true );
}
void PluginRegistrationDialog::OnCancel(wxCommandEvent &event)
{
EndModal(false);
}
///////////////////////////////////////////////////////////////////////////////
//
// VSTEffectDialog
@@ -1679,6 +1839,47 @@ void VSTEffect::Unload()
}
}
void VSTEffect::ScanOnePlugin( const wxString & file )
{
const wxChar * argv[4];
argv[0] = PlatformCompatibility::GetExecutablePath().c_str();
argv[1] = VSTCMDKEY;
argv[2] = file.c_str();
argv[3] = NULL;
// ToDo: do we need a try--catch around this in case a bad plug-in
// fails? (JKC Nov09)
wxExecute((wxChar **) argv, wxEXEC_SYNC | wxEXEC_NODISABLE, NULL);
}
void VSTEffect::ShowPluginListDialog( const wxArrayString & files )
{
PluginRegistrationDialog d( wxGetApp().GetTopWindow(), files );
d.ShowModal();
}
void VSTEffect::ShowProgressDialog( const wxString & longest, const wxArrayString & files )
{
ProgressDialog *progress = new ProgressDialog(_("Scanning VST Plugins"),
longest,
pdlgHideStopButton);
// progress->SetSize(wxSize(500, -1));
progress->CenterOnScreen();
size_t cnt = files.GetCount();
for (size_t i = 0; i < cnt; i++) {
wxString file = files[i];
int status = progress->Update(wxLongLong(i),
wxLongLong(cnt),
wxString::Format(_("Checking %s"), file.c_str()));
if (status != eProgressSuccess) {
break;
}
ScanOnePlugin( file );
}
delete progress;
}
/* static */
void VSTEffect::Scan()
{
@@ -1774,6 +1975,8 @@ void VSTEffect::Scan()
#endif
files.Sort();
// This is a hack to allow for long paths in the progress dialog. The
// progress dialog should really truncate the message if it's too wide
// for the dialog.
@@ -1790,35 +1993,10 @@ void VSTEffect::Scan()
longest = files[i];
}
}
ProgressDialog *progress = new ProgressDialog(_("Scanning VST Plugins"),
longest,
pdlgHideStopButton);
// progress->SetSize(wxSize(500, -1));
progress->CenterOnScreen();
const wxChar * argv[4];
argv[0] = PlatformCompatibility::GetExecutablePath().c_str();
argv[1] = VSTCMDKEY;
argv[2] = NULL;
argv[3] = NULL;
for (size_t i = 0; i < cnt; i++) {
wxString file = files[i];
int status = progress->Update(wxLongLong(i),
wxLongLong(cnt),
wxString::Format(_("Checking %s"), file.c_str()));
if (status != eProgressSuccess) {
break;
}
argv[2] = file.c_str();
// ToDo: do we need a try--catch around this in case a bad plug-in
// fails? (JKC Nov09)
wxExecute((wxChar **) argv, wxEXEC_SYNC | wxEXEC_NODISABLE, NULL);
}
delete progress;
//Choose the first for the original version which scans them all
//The second to selectively scan.
//ShowProgressDialog( longest, files );
ShowPluginListDialog( files );
}
/* static */

View File

@@ -68,6 +68,12 @@ class VSTEffect:public Effect
static void Scan();
static void Check(const wxChar *fname);
static void ScanOnePlugin( const wxString & file );
static void ShowPluginListDialog( const wxArrayString & files );
static void ShowProgressDialog( const wxString & longest, const wxArrayString & files );
// Utility methods
int GetChannels();