1
0
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:
martynshaw99 2013-06-05 00:35:10 +00:00
parent 44c03e7de8
commit 37f74e27bb
5 changed files with 78 additions and 138 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();
} }

View File

@ -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__