mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-03 17:39:25 +02:00
Adding the ability to load 'non-recognised' modules, with a warning to the user (the main point).
Removing duplicate code from LoadModules, at the expense of making ModuleManager::Initialize more monolithic. Make MultiDialog a bit more general. Remove a few warnings. Some logging has been turned back on when loading libs, we could turn it off again. To test you could compile mod-nyq-bench and make sure it is available on the bottom of the 'View' menu, then unselect it in the Prefs -> Modules an retry.
This commit is contained in:
parent
44c03e7de8
commit
37f74e27bb
@ -1128,14 +1128,11 @@ bool AudacityApp::OnInit()
|
|||||||
wxFrame *temporarywindow = new wxFrame(NULL, -1, wxT("temporarytopwindow"));
|
wxFrame *temporarywindow = new wxFrame(NULL, -1, wxT("temporarytopwindow"));
|
||||||
SetTopWindow(temporarywindow);
|
SetTopWindow(temporarywindow);
|
||||||
|
|
||||||
// Initialize the ModuleManager
|
|
||||||
ModuleManager::Initialize();
|
|
||||||
|
|
||||||
// Initialize the CommandHandler
|
// Initialize the CommandHandler
|
||||||
InitCommandHandler();
|
InitCommandHandler();
|
||||||
|
|
||||||
// load audacity plug-in modules
|
// Initialize the ModuleManager, including loading found modules
|
||||||
LoadModules(*mCmdHandler);
|
ModuleManager::Initialize(*mCmdHandler);
|
||||||
|
|
||||||
// Locale
|
// Locale
|
||||||
// wxWidgets 2.3 has a much nicer wxLocale API. We can make this code much
|
// wxWidgets 2.3 has a much nicer wxLocale API. We can make this code much
|
||||||
|
@ -33,6 +33,7 @@ i.e. an alternative to the usual interface, for Audacity.
|
|||||||
|
|
||||||
#include "Prefs.h"
|
#include "Prefs.h"
|
||||||
#include "LoadModules.h"
|
#include "LoadModules.h"
|
||||||
|
#include "widgets/MultiDialog.h"
|
||||||
|
|
||||||
#define initFnName "ExtensionModuleInit"
|
#define initFnName "ExtensionModuleInit"
|
||||||
#define versionFnName "GetVersionString"
|
#define versionFnName "GetVersionString"
|
||||||
@ -92,84 +93,6 @@ bool IsAllowedModule( wxString fname )
|
|||||||
return bLoad;
|
return bLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadModule(wxString fname)
|
|
||||||
{
|
|
||||||
if( !IsAllowedModule( fname ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxLogDebug(wxT("About to load module %s"), fname.c_str());
|
|
||||||
wxLogNull logNo; // Don't show wxWidgets Error if cannot load within this method. (Fix bug 544.)
|
|
||||||
|
|
||||||
tModuleInit mainFn = NULL;
|
|
||||||
|
|
||||||
// As a courtesy to some modules that might be bridges to
|
|
||||||
// open other modules, we set the current working
|
|
||||||
// directory to be the module's directory.
|
|
||||||
|
|
||||||
wxString saveOldCWD = ::wxGetCwd();
|
|
||||||
wxString prefix = ::wxPathOnly(fname);
|
|
||||||
::wxSetWorkingDirectory(prefix);
|
|
||||||
|
|
||||||
wxDynamicLibrary* pDLL = new wxDynamicLibrary();
|
|
||||||
if (pDLL && pDLL->Load(fname, wxDL_LAZY))
|
|
||||||
{
|
|
||||||
// We've loaded and initialised OK.
|
|
||||||
// So look for special case functions:
|
|
||||||
// (a) for scripting.
|
|
||||||
if( scriptFn == NULL )
|
|
||||||
scriptFn = (tpRegScriptServerFunc)(pDLL->GetSymbol(wxT(scriptFnName)));
|
|
||||||
// (b) for hijacking the entire Audacity panel.
|
|
||||||
if( pPanelHijack==NULL )
|
|
||||||
pPanelHijack = (tPanelFn)(pDLL->GetSymbol(wxT(mainPanelFnName)));
|
|
||||||
}
|
|
||||||
|
|
||||||
::wxSetWorkingDirectory(saveOldCWD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadModules(CommandHandler &cmdHandler)
|
|
||||||
{
|
|
||||||
wxArrayString audacityPathList = wxGetApp().audacityPathList;
|
|
||||||
wxArrayString pathList;
|
|
||||||
wxArrayString files;
|
|
||||||
wxString pathVar;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Code from LoadLadspa that might be useful in load modules.
|
|
||||||
pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH"));
|
|
||||||
if (pathVar != wxT(""))
|
|
||||||
wxGetApp().AddMultiPathsToPathList(pathVar, pathList);
|
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
|
||||||
wxGetApp().AddUniquePathToPathList(INSTALL_PREFIX wxT("/modules"), pathList);
|
|
||||||
wxGetApp().AddUniquePathToPathList(wxT("/usr/local/lib/modules"), pathList);
|
|
||||||
wxGetApp().AddUniquePathToPathList(wxT("/usr/lib/modules"), pathList);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(i=0; i<audacityPathList.GetCount(); i++) {
|
|
||||||
wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
|
|
||||||
wxGetApp().AddUniquePathToPathList(prefix + wxT("modules"),
|
|
||||||
pathList);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files);
|
|
||||||
#else
|
|
||||||
wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(i=0; i<files.GetCount(); i++)
|
|
||||||
LoadModule(files[i]);
|
|
||||||
// After loading all the modules, we may have a registered scripting function.
|
|
||||||
if(scriptFn)
|
|
||||||
{
|
|
||||||
ScriptCommandRelay::SetCommandHandler(cmdHandler);
|
|
||||||
ScriptCommandRelay::SetRegScriptServerFunc(scriptFn);
|
|
||||||
NonGuiThread::StartChild(&ScriptCommandRelay::Run);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Module::Module(const wxString & name)
|
Module::Module(const wxString & name)
|
||||||
{
|
{
|
||||||
mName = name;
|
mName = name;
|
||||||
@ -184,7 +107,7 @@ Module::~Module()
|
|||||||
|
|
||||||
bool Module::Load()
|
bool Module::Load()
|
||||||
{
|
{
|
||||||
wxLogNull logNo;
|
// wxLogNull logNo;
|
||||||
|
|
||||||
if (mLib->IsLoaded()) {
|
if (mLib->IsLoaded()) {
|
||||||
if (mDispatch) {
|
if (mDispatch) {
|
||||||
@ -243,8 +166,13 @@ int Module::Dispatch(ModuleDispatchTypes type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void * Module::GetSymbol(wxString name)
|
||||||
|
{
|
||||||
|
return mLib->GetSymbol(name);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Module Manager (using wxPluginManager would be MUCH better)
|
// Module Manager
|
||||||
//
|
//
|
||||||
ModuleManager *ModuleManager::mInstance;
|
ModuleManager *ModuleManager::mInstance;
|
||||||
|
|
||||||
@ -265,7 +193,7 @@ void ModuleManager::OnExit()
|
|||||||
mModules.Clear();
|
mModules.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleManager::Initialize()
|
void ModuleManager::Initialize(CommandHandler &cmdHandler)
|
||||||
{
|
{
|
||||||
wxArrayString audacityPathList = wxGetApp().audacityPathList;
|
wxArrayString audacityPathList = wxGetApp().audacityPathList;
|
||||||
wxArrayString pathList;
|
wxArrayString pathList;
|
||||||
@ -273,12 +201,10 @@ void ModuleManager::Initialize()
|
|||||||
wxString pathVar;
|
wxString pathVar;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
// JKC: Is this code duplicating LoadModules() ????
|
|
||||||
// Code from LoadLadspa that might be useful in load modules.
|
// Code from LoadLadspa that might be useful in load modules.
|
||||||
pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH"));
|
pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH"));
|
||||||
if (pathVar != wxT("")) {
|
if (pathVar != wxT(""))
|
||||||
wxGetApp().AddMultiPathsToPathList(pathVar, pathList);
|
wxGetApp().AddMultiPathsToPathList(pathVar, pathList);
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < audacityPathList.GetCount(); i++) {
|
for (i = 0; i < audacityPathList.GetCount(); i++) {
|
||||||
wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
|
wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
|
||||||
@ -288,24 +214,59 @@ void ModuleManager::Initialize()
|
|||||||
|
|
||||||
#if defined(__WXMSW__)
|
#if defined(__WXMSW__)
|
||||||
wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files);
|
wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files);
|
||||||
// #elif defined(__WXMAC__)
|
|
||||||
// wxGetApp().FindFilesInPathList(wxT("*.dylib"), pathList, files);
|
|
||||||
#else
|
#else
|
||||||
wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files);
|
wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < files.GetCount(); i++) {
|
for (i = 0; i < files.GetCount(); i++) {
|
||||||
if( IsAllowedModule( files[i] ) )
|
if( !IsAllowedModule( files[i] ) )
|
||||||
{
|
{
|
||||||
Module *module = new Module(files[i]);
|
wxString ShortName = wxFileName( files[i] ).GetName();
|
||||||
|
wxString msg;
|
||||||
|
msg.Printf(_("Unkown Module \"%s\""), ShortName.c_str());
|
||||||
|
const wxChar *buttons[] = {_("Yes"), _("No"), NULL}; // could add a button here for 'yes and remember that', and put it into the cfg file
|
||||||
|
int action;
|
||||||
|
action = ShowMultiDialog(msg, _("Warning - Unknown Module"), buttons, _("Load this module?"), false);
|
||||||
|
if(action == 1) // "No"
|
||||||
|
continue;
|
||||||
|
wxLogDebug(wxT("Unknown module %s accepted"), ShortName.c_str());
|
||||||
|
}
|
||||||
|
wxLogDebug(wxT("About to load module %s"), wxFileName( files[i] ).GetName().c_str());
|
||||||
|
|
||||||
if (module->Load()) {
|
// As a courtesy to some modules that might be bridges to
|
||||||
mInstance->mModules.Add(module);
|
// open other modules, we set the current working
|
||||||
}
|
// directory to be the module's directory.
|
||||||
else {
|
wxString saveOldCWD = ::wxGetCwd();
|
||||||
delete module;
|
wxString prefix = ::wxPathOnly(files[i]);
|
||||||
|
::wxSetWorkingDirectory(prefix);
|
||||||
|
|
||||||
|
Module *module = new Module(files[i]);
|
||||||
|
|
||||||
|
if (module->Load()) {
|
||||||
|
mInstance->mModules.Add(module);
|
||||||
|
// We've loaded and initialised OK.
|
||||||
|
// So look for special case functions:
|
||||||
|
wxLogNull logNo; // Don't show wxWidgets errors if we can't do these. (Was: Fix bug 544.)
|
||||||
|
// (a) for scripting.
|
||||||
|
if( scriptFn == NULL )
|
||||||
|
scriptFn = (tpRegScriptServerFunc)(module->GetSymbol(wxT(scriptFnName)));
|
||||||
|
// (b) for hijacking the entire Audacity panel.
|
||||||
|
if( pPanelHijack==NULL )
|
||||||
|
{
|
||||||
|
pPanelHijack = (tPanelFn)(module->GetSymbol(wxT(mainPanelFnName)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
delete module;
|
||||||
|
}
|
||||||
|
::wxSetWorkingDirectory(saveOldCWD);
|
||||||
|
}
|
||||||
|
// After loading all the modules, we may have a registered scripting function.
|
||||||
|
if(scriptFn)
|
||||||
|
{
|
||||||
|
ScriptCommandRelay::SetCommandHandler(cmdHandler);
|
||||||
|
ScriptCommandRelay::SetRegScriptServerFunc(scriptFn);
|
||||||
|
NonGuiThread::StartChild(&ScriptCommandRelay::Run);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,14 +283,3 @@ int ModuleManager::Dispatch(ModuleDispatchTypes type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(ModuleManager, wxModule);
|
IMPLEMENT_DYNAMIC_CLASS(ModuleManager, wxModule);
|
||||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
|
||||||
// version control system. Please do not modify past this point.
|
|
||||||
//
|
|
||||||
// Local Variables:
|
|
||||||
// c-basic-offset: 3
|
|
||||||
// indent-tabs-mode: nil
|
|
||||||
// End:
|
|
||||||
//
|
|
||||||
// vim: et sts=3 sw=3
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,9 +17,6 @@
|
|||||||
|
|
||||||
class CommandHandler;
|
class CommandHandler;
|
||||||
|
|
||||||
void LoadModules(CommandHandler &cmdHandler);
|
|
||||||
void LoadModule(wxString fname);
|
|
||||||
|
|
||||||
wxWindow * MakeHijackPanel();
|
wxWindow * MakeHijackPanel();
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -51,6 +48,7 @@ public:
|
|||||||
bool Load();
|
bool Load();
|
||||||
void Unload();
|
void Unload();
|
||||||
int Dispatch(ModuleDispatchTypes type);
|
int Dispatch(ModuleDispatchTypes type);
|
||||||
|
void * GetSymbol(wxString name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxString mName;
|
wxString mName;
|
||||||
@ -67,7 +65,7 @@ public:
|
|||||||
virtual bool OnInit();
|
virtual bool OnInit();
|
||||||
virtual void OnExit();
|
virtual void OnExit();
|
||||||
|
|
||||||
static void Initialize();
|
static void Initialize(CommandHandler &cmdHandler);
|
||||||
static int Dispatch(ModuleDispatchTypes type);
|
static int Dispatch(ModuleDispatchTypes type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -79,14 +77,3 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __AUDACITY_LOADMODULES_H__ */
|
#endif /* __AUDACITY_LOADMODULES_H__ */
|
||||||
|
|
||||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
|
||||||
// version control system. Please do not modify past this point.
|
|
||||||
//
|
|
||||||
// Local Variables:
|
|
||||||
// c-basic-offset: 3
|
|
||||||
// indent-tabs-mode: nil
|
|
||||||
// End:
|
|
||||||
//
|
|
||||||
// vim: et sts=3 sw=3
|
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class MultiDialog : public wxDialog
|
|||||||
public:
|
public:
|
||||||
MultiDialog(wxString message,
|
MultiDialog(wxString message,
|
||||||
wxString title,
|
wxString title,
|
||||||
const wxChar **buttons);
|
const wxChar **buttons, wxString boxMsg, bool log);
|
||||||
~MultiDialog() {};
|
~MultiDialog() {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -59,7 +59,7 @@ END_EVENT_TABLE()
|
|||||||
|
|
||||||
MultiDialog::MultiDialog(wxString message,
|
MultiDialog::MultiDialog(wxString message,
|
||||||
wxString title,
|
wxString title,
|
||||||
const wxChar **buttons)
|
const wxChar **buttons, wxString boxMsg, bool log)
|
||||||
: wxDialog(NULL, (wxWindowID)-1, title,
|
: wxDialog(NULL, (wxWindowID)-1, title,
|
||||||
wxDefaultPosition, wxDefaultSize,
|
wxDefaultPosition, wxDefaultSize,
|
||||||
wxCAPTION) // not wxDEFAULT_DIALOG_STYLE because we don't want wxCLOSE_BOX and wxSYSTEM_MENU
|
wxCAPTION) // not wxDEFAULT_DIALOG_STYLE because we don't want wxCLOSE_BOX and wxSYSTEM_MENU
|
||||||
@ -91,24 +91,30 @@ MultiDialog::MultiDialog(wxString message,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mRadioBox = new wxRadioBox(this,-1,
|
mRadioBox = new wxRadioBox(this,-1,
|
||||||
_(" Please select an action "),
|
boxMsg,
|
||||||
wxDefaultPosition, wxDefaultSize,
|
wxDefaultPosition, wxDefaultSize,
|
||||||
count, buttonLabels,
|
count, buttonLabels,
|
||||||
1, wxRA_SPECIFY_COLS);
|
1, wxRA_SPECIFY_COLS);
|
||||||
mRadioBox->SetName(_("Please select an action"));
|
mRadioBox->SetName(boxMsg);
|
||||||
mRadioBox->SetSelection(0);
|
mRadioBox->SetSelection(0);
|
||||||
vSizer->Add(mRadioBox, 1, wxEXPAND | wxALIGN_CENTER | wxALL, 5);
|
vSizer->Add(mRadioBox, 1, wxEXPAND | wxALIGN_CENTER | wxALL, 5);
|
||||||
|
|
||||||
|
|
||||||
wxBoxSizer* buttonSizer = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer* buttonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
wxButton* pButton = new wxButton(this, ID_SHOW_LOG_BUTTON, _("Show Log for Details"));
|
wxButton* pButton;
|
||||||
buttonSizer->Add(pButton, 0, wxALIGN_LEFT | wxALL, 5);
|
if(log)
|
||||||
pButton->SetDefault(); // Encourage user to look at files.
|
{
|
||||||
|
pButton = new wxButton(this, ID_SHOW_LOG_BUTTON, _("Show Log for Details"));
|
||||||
|
buttonSizer->Add(pButton, 0, wxALIGN_LEFT | wxALL, 5);
|
||||||
|
pButton->SetDefault(); // Encourage user to look at files.
|
||||||
|
|
||||||
buttonSizer->AddSpacer(40);
|
buttonSizer->AddSpacer(40);
|
||||||
|
}
|
||||||
|
|
||||||
pButton = new wxButton(this, wxID_OK, _("OK"));
|
pButton = new wxButton(this, wxID_OK, _("OK"));
|
||||||
|
if(!log)
|
||||||
|
pButton->SetDefault();
|
||||||
buttonSizer->Add(pButton, 0, wxALIGN_RIGHT | wxALL, 5);
|
buttonSizer->Add(pButton, 0, wxALIGN_RIGHT | wxALL, 5);
|
||||||
|
|
||||||
vSizer->Add(buttonSizer, 0, wxALIGN_CENTER | wxALL, 5);
|
vSizer->Add(buttonSizer, 0, wxALIGN_CENTER | wxALL, 5);
|
||||||
@ -122,12 +128,12 @@ MultiDialog::MultiDialog(wxString message,
|
|||||||
delete[] buttonLabels;
|
delete[] buttonLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDialog::OnOK(wxCommandEvent &event)
|
void MultiDialog::OnOK(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
EndModal(mRadioBox->GetSelection());
|
EndModal(mRadioBox->GetSelection());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDialog::OnShowLog(wxCommandEvent &event)
|
void MultiDialog::OnShowLog(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
GetActiveProject()->OnShowLog();
|
GetActiveProject()->OnShowLog();
|
||||||
}
|
}
|
||||||
@ -135,9 +141,9 @@ void MultiDialog::OnShowLog(wxCommandEvent &event)
|
|||||||
|
|
||||||
int ShowMultiDialog(wxString message,
|
int ShowMultiDialog(wxString message,
|
||||||
wxString title,
|
wxString title,
|
||||||
const wxChar **buttons)
|
const wxChar **buttons, wxString boxMsg, bool log)
|
||||||
{
|
{
|
||||||
MultiDialog dlog(message, title, buttons);
|
MultiDialog dlog(message, title, buttons, boxMsg, log);
|
||||||
dlog.CentreOnParent();
|
dlog.CentreOnParent();
|
||||||
return dlog.ShowModal();
|
return dlog.ShowModal();
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,6 @@
|
|||||||
// Return the zero-based index of the chosen button.
|
// Return the zero-based index of the chosen button.
|
||||||
int ShowMultiDialog(wxString message,
|
int ShowMultiDialog(wxString message,
|
||||||
wxString title,
|
wxString title,
|
||||||
const wxChar **buttons);
|
const wxChar **buttons, wxString boxMsg = _("Please select an action"), bool log = true);
|
||||||
|
|
||||||
#endif // __AUDACITY_MULTIDIALOG__
|
#endif // __AUDACITY_MULTIDIALOG__
|
||||||
|
Loading…
x
Reference in New Issue
Block a user