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:
164
images/Arrow.xpm
164
images/Arrow.xpm
@@ -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+. ",
|
||||
" .+++;#@;++++. ",
|
||||
" ............. ",
|
||||
" "};
|
||||
|
@@ -185,6 +185,7 @@ void PluginManager::PurgeType(const wxString & type)
|
||||
|
||||
path.Printf(wxT("/%s"), type.c_str());
|
||||
|
||||
SetDirty();
|
||||
mConfig->DeleteGroup(path);
|
||||
}
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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();
|
||||
|
Reference in New Issue
Block a user