diff --git a/src/LoadModules.cpp b/src/LoadModules.cpp index 3d2679cbd..ffd677f1e 100644 --- a/src/LoadModules.cpp +++ b/src/LoadModules.cpp @@ -34,7 +34,9 @@ i.e. an alternative to the usual interface, for Audacity. #ifdef EXPERIMENTAL_MODULE_PREFS #include "Prefs.h" +#include "./prefs/ModulePrefs.h" #endif + #include "LoadModules.h" #include "widgets/MultiDialog.h" @@ -77,27 +79,6 @@ wxWindow * MakeHijackPanel() // starts a thread and reads script commands. static tpRegScriptServerFunc scriptFn; -#ifdef EXPERIMENTAL_MODULE_PREFS -bool IsAllowedModule( wxString fname ) -{ - bool bLoad = false; - wxString ShortName = wxFileName( fname ).GetName(); - if( (ShortName.CmpNoCase( wxT("mod-script-pipe")) == 0 )) - { - gPrefs->Read(wxT("/Module/mod-script-pipe"), &bLoad, false); - } - else if( (ShortName.CmpNoCase( wxT("mod-nyq-bench")) == 0 )) - { - gPrefs->Read(wxT("/Module/mod-nyq-bench"), &bLoad, false); - } - else if( (ShortName.CmpNoCase( wxT("mod-track-panel")) == 0 )) - { - gPrefs->Read(wxT("/Module/mod-track-panel"), &bLoad, false); - } - return bLoad; -} -#endif // EXPERIMENTAL_MODULE_PREFS - Module::Module(const wxString & name) { mName = name; @@ -236,8 +217,19 @@ void ModuleManager::Initialize(CommandHandler &cmdHandler) ::wxSetWorkingDirectory(prefix); #ifdef EXPERIMENTAL_MODULE_PREFS - if( !IsAllowedModule( files[i] ) ) // don't try and check the in-date-ness before this as that means loading the module to call it's GetVersionString, which could do anything. + int iModuleStatus = ModulePrefs::GetModuleStatus( files[i] ); + if( iModuleStatus == kModuleDisabled ) + continue; + if( iModuleStatus == kModuleFailed ) + continue; + + if( (iModuleStatus == kModuleAsk ) || + (iModuleStatus == kModuleNew ) + ) #endif + // JKC: I don't like prompting for the plug-ins individually + // I think it would be better to show the module prefs page, + // and let the user decide for each one. { wxString ShortName = wxFileName( files[i] ).GetName(); wxString msg; @@ -246,9 +238,22 @@ void ModuleManager::Initialize(CommandHandler &cmdHandler) const wxChar *buttons[] = {_("Yes"), _("No"), NULL}; // could add a button here for 'yes and remember that', and put it into the cfg file. Needs more thought. int action; action = ShowMultiDialog(msg, _("Module Loader"), buttons, _("Try and load this module?"), false); - if(action == 1) // "No" +#ifdef EXPERIMENTAL_MODULE_PREFS + // If we're not prompting always, accept the answer permanantly + if( iModuleStatus == kModuleNew ){ + iModuleStatus = (action==1)?kModuleDisabled : kModuleEnabled; + ModulePrefs::SetModuleStatus( files[i], iModuleStatus ); + } +#endif + if(action == 1){ // "No" continue; + } } +#ifdef EXPERIMENTAL_MODULE_PREFS + // Before attempting to load, we set the state to bad. + // That way, if we crash, we won't try again. + ModulePrefs::SetModuleStatus( files[i], kModuleFailed ); +#endif Module *module = new Module(files[i]); if (module->Load()) // it will get rejected if there are version problems @@ -265,8 +270,13 @@ void ModuleManager::Initialize(CommandHandler &cmdHandler) { pPanelHijack = (tPanelFn)(module->GetSymbol(wxT(mainPanelFnName))); } +#ifdef EXPERIMENTAL_MODULE_PREFS + // Loaded successfully, restore the status. + ModulePrefs::SetModuleStatus( files[i], iModuleStatus); +#endif } else { + // No need to save status, as we already set kModuleFailed. delete module; } ::wxSetWorkingDirectory(saveOldCWD); diff --git a/src/prefs/ModulePrefs.cpp b/src/prefs/ModulePrefs.cpp index a515fafa7..798f758ea 100644 --- a/src/prefs/ModulePrefs.cpp +++ b/src/prefs/ModulePrefs.cpp @@ -37,8 +37,41 @@ ModulePrefs::~ModulePrefs() { } +void ModulePrefs::GetAllModuleStatuses(){ + wxString str; + long dummy; + + // Modules could for example be: + // mod-script-pipe + // mod-nyq-bench + // mod-track-panel + + mModules.Clear(); + mStatuses.Clear(); + + + // Iterate through all Modules listed in prefs. + // Get their names and values. + gPrefs->SetPath( wxT("Module/") ); + bool bCont = gPrefs->GetFirstEntry(str, dummy); + while ( bCont ) { + int iStatus; + gPrefs->Read( str, &iStatus, kModuleDisabled ); + if( iStatus > kModuleNew ){ + iStatus = kModuleNew; + gPrefs->Write( str, iStatus ); + } + //wxLogDebug( wxT("Entry: %s Value: %i"), str.c_str(), iStatus ); + mModules.Add( str ); + mStatuses.Add( iStatus ); + bCont = gPrefs->GetNextEntry(str, dummy); + } + gPrefs->SetPath( wxT("") ); +} + void ModulePrefs::Populate() { + GetAllModuleStatuses(); //------------------------- Main section -------------------- // Now construct the GUI itself. // Use 'eIsCreatingFromPrefs' so that the GUI is @@ -50,20 +83,26 @@ void ModulePrefs::Populate() void ModulePrefs::PopulateOrExchange(ShuttleGui & S) { + wxArrayString StatusChoices; + StatusChoices.Add( _("Disabled" ) ); + StatusChoices.Add( _("Enabled" ) ); + StatusChoices.Add( _("Ask" ) ); + StatusChoices.Add( _("Failed" ) ); + StatusChoices.Add( _("New" ) ); S.SetBorder(2); - S.StartStatic(_("Enable these Modules (if present), next time Audacity is started")); + S.StartStatic(_("")); { - S.AddFixedText(_("These are experimental. Enable them only if you've read the manual\nand know what you are doing.") ); - S.TieCheckBox(_("mod-&script-pipe"), - wxT("/Module/mod-script-pipe"), - false); - S.TieCheckBox(_("mod-&nyq-bench"), - wxT("/Module/mod-nyq-bench"), - false); - S.TieCheckBox(_("mod-&track-panel"), - wxT("/Module/mod-track-panel"), - false); + S.AddFixedText(_("These are experimental Modules. Enable them only if you've read the manual\nand know what you are doing.") ); + S.AddFixedText(wxString(wxT(" ")) + _("'Ask' means Audacity will ask if you want to load the plug-each time it starts.") ); + S.AddFixedText(wxString(wxT(" ")) + _("'Failed' means Audacity thinks the plug-in is broken and won't run it.") ); + S.AddFixedText(wxString(wxT(" ")) + _("'New' is like 'Ask', but asks just once.") ); + S.StartMultiColumn( 2 ); + int i; + for(i=0;i<(int)mModules.GetCount();i++) + S.TieChoice( mModules[i], mStatuses[i], &StatusChoices ); + S.EndMultiColumn(); + } S.EndStatic(); } @@ -72,6 +111,33 @@ bool ModulePrefs::Apply() { ShuttleGui S(this, eIsSavingToPrefs); PopulateOrExchange(S); - + int i; + for(i=0;i<(int)mModules.GetCount();i++) + SetModuleStatus( mModules[i], mStatuses[i] ); return true; } + + +// static function that tells us about a module. +int ModulePrefs::GetModuleStatus( wxString fname ){ + // Default status is new module, and we will ask once. + int iStatus = kModuleNew; + + wxString ShortName = wxFileName( fname ).GetName(); + wxString PrefName = wxString( wxT("/Module/") ) + ShortName.Lower(); + + gPrefs->Read( PrefName, &iStatus, kModuleNew ); + // fix up a bad status. + if( iStatus > kModuleNew ) + iStatus=kModuleNew; + return iStatus; +} + +void ModulePrefs::SetModuleStatus( wxString fname, int iStatus ){ + wxString ShortName = wxFileName( fname ).GetName(); + wxString PrefName = wxString( wxT("/Module/") ) + ShortName.Lower(); + gPrefs->Write( PrefName, iStatus ); +} + + + diff --git a/src/prefs/ModulePrefs.h b/src/prefs/ModulePrefs.h index aff3db62b..33d83d2ab 100644 --- a/src/prefs/ModulePrefs.h +++ b/src/prefs/ModulePrefs.h @@ -21,6 +21,16 @@ #include "PrefsPanel.h" + +enum { + kModuleDisabled = 0, + kModuleEnabled = 1, + kModuleAsk = 2, // Will ask, each time, when audacity starts. + kModuleFailed = 3, // Audacity thinks this is a bad module. + kModuleNew = 4 // Audacity will ask once, and remember the answer. +}; + + class ModulePrefs:public PrefsPanel { public: @@ -28,9 +38,15 @@ class ModulePrefs:public PrefsPanel ~ModulePrefs(); virtual bool Apply(); + static int GetModuleStatus( wxString fname ); + static void SetModuleStatus( wxString fname, int iStatus ); + private: + void GetAllModuleStatuses(); void Populate(); void PopulateOrExchange(ShuttleGui & S); + wxArrayString mModules; + wxArrayInt mStatuses; }; #endif