Beispiel #1
0
// static 
void ModuleManager::Initialize(CommandHandler &cmdHandler)
{
   wxArrayString audacityPathList = wxGetApp().audacityPathList;
   wxArrayString pathList;
   wxArrayString files;
   wxString pathVar;
   size_t i;

   // Code from LoadLadspa that might be useful in load modules.
   pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH"));
   if (pathVar != wxT(""))
      wxGetApp().AddMultiPathsToPathList(pathVar, pathList);

   for (i = 0; i < audacityPathList.GetCount(); i++) {
      wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
      wxGetApp().AddUniquePathToPathList(prefix + wxT("modules"),
                                         pathList);
   }

   #if defined(__WXMSW__)
   wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files);
   #else
   wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files);
   #endif

   wxString saveOldCWD = ::wxGetCwd();
   for (i = 0; i < files.GetCount(); i++) {
      // 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 prefix = ::wxPathOnly(files[i]);
      ::wxSetWorkingDirectory(prefix);

#ifdef EXPERIMENTAL_MODULE_PREFS
      int iModuleStatus = ModulePrefs::GetModuleStatus( files[i] );
      if( iModuleStatus == kModuleDisabled )
         continue;
      if( iModuleStatus == kModuleFailed )
         continue;
      // New module?  You have to go and explicitly enable it.
      if( iModuleStatus == kModuleNew ){
         // To ensure it is noted in config file and so
         // appears on modules page.
         ModulePrefs::SetModuleStatus( files[i], kModuleNew);
         continue;
      }

      if( iModuleStatus == kModuleAsk )
#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;
         msg.Printf(_("Module \"%s\" found."), ShortName.c_str());
         msg += _("\n\nOnly use modules from trusted sources");
         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, _("Audacity Module Loader"), buttons, _("Try and load this module?"), false);
#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
      {
         Get().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)));
         }
#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);

   // After loading all the modules, we may have a registered scripting function.
   if(scriptFn)
   {
      ScriptCommandRelay::SetCommandHandler(cmdHandler);
      ScriptCommandRelay::SetRegScriptServerFunc(scriptFn);
      NonGuiThread::StartChild(&ScriptCommandRelay::Run);
   }
}
void ModuleManager::Initialize(CommandHandler &cmdHandler)
{
   wxArrayString audacityPathList = wxGetApp().audacityPathList;
   wxArrayString pathList;
   wxArrayString files;
   wxString pathVar;
   size_t i;

   // Code from LoadLadspa that might be useful in load modules.
   pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH"));
   if (pathVar != wxT(""))
      wxGetApp().AddMultiPathsToPathList(pathVar, pathList);

   for (i = 0; i < audacityPathList.GetCount(); i++) {
      wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
      wxGetApp().AddUniquePathToPathList(prefix + wxT("modules"),
                                         pathList);
   }

   #if defined(__WXMSW__)
   wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files);   
   #else
   wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files);
   #endif

   for (i = 0; i < files.GetCount(); i++) {
      // 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(files[i]);
      ::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.
#endif
      {
         wxString ShortName = wxFileName( files[i] ).GetName();
         wxString msg;
         msg.Printf(_("Module \"%s\" found."), ShortName.c_str());
         msg += _("\n\nOnly use modules from trusted sources");
         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"
            continue;
      }

      Module *module = new Module(files[i]);
      if (module->Load())   // it will get rejected if there  are version problems
      {
         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);
   }
}
Beispiel #3
0
int DirManager::ProjectFSCK(bool forceerror, bool silentlycorrect)
{
      
   // get a rough guess of how many blockfiles will be found/processed
   // at each step by looking at the size of the blockfile hash
   int blockcount=blockFileHash.size();
   int ret=0;
   int ndx;

   // enumerate *all* files in the project directory
   wxArrayString fnameList;

   wxArrayString orphanList;
   BlockHash    missingAliasList;
   BlockHash    missingAliasFiles;
   BlockHash    missingSummaryList;
   BlockHash    missingDataList;

   // this function is finally a misnomer
   rm_dash_rf_enumerate_prompt((projFull != wxT("")? projFull: mytemp),
                               fnameList,wxEmptyString,1,0,blockcount,
                               _("Inspecting project file data..."));
   
   // enumerate orphaned blockfiles
   BlockHash diskFileHash;
   for(ndx=0;ndx<(int)fnameList.GetCount();ndx++){
      wxFileName fullname = fnameList[ndx];
      wxString basename=fullname.GetName();
      
      diskFileHash[basename.c_str()]=0; // just needs to be defined
      if(blockFileHash.find(basename) == blockFileHash.end()){
         // the blockfile on disk is orphaned
         orphanList.Add(fullname.GetFullPath());
         if (!silentlycorrect)
            wxLogWarning(_("Orphaned blockfile: (%s)"),
                         fullname.GetFullPath().c_str());
      }
   }
   
   // enumerate missing alias files
   BlockHash::iterator i=blockFileHash.begin();
   while(i != blockFileHash.end()) {
      wxString key=i->first;
      BlockFile *b=i->second;
      
      if(b->IsAlias()){
         wxFileName aliasfile=((AliasBlockFile *)b)->GetAliasedFile();
         if(aliasfile.GetFullPath()!=wxEmptyString && !wxFileExists(aliasfile.GetFullPath())){
            missingAliasList[key]=b;
            missingAliasFiles[aliasfile.GetFullPath().c_str()]=0; // simply must be defined
         }
      }
      i++;
   }

   if (!silentlycorrect) {
      i=missingAliasFiles.begin();
      while(i != missingAliasFiles.end()) {
         wxString key=i->first;
         wxLogWarning(_("Missing alias file: (%s)"),key.c_str());
         i++;
      }
   }

   // enumerate missing summary blockfiles
   i=blockFileHash.begin();
   while(i != blockFileHash.end()) {
      wxString key=i->first;
      BlockFile *b=i->second;
      
      if(b->IsAlias()){
         /* don't look in hash; that might find files the user moved
            that the Blockfile abstraction can't find itself */
         wxFileName file=MakeBlockFilePath(key);
         file.SetName(key);
         file.SetExt(wxT("auf"));
         if(!wxFileExists(file.GetFullPath().c_str())){
            missingSummaryList[key]=b;
            if (!silentlycorrect)
               wxLogWarning(_("Missing summary file: (%s.auf)"),
                            key.c_str());
         }
      }
      i++;
   }

   // enumerate missing data blockfiles
   i=blockFileHash.begin();
   while(i != blockFileHash.end()) {
      wxString key=i->first;
      BlockFile *b=i->second;

      if(!b->IsAlias()){
         wxFileName file=MakeBlockFilePath(key);
         file.SetName(key);
         file.SetExt(wxT("au"));
         if(!wxFileExists(file.GetFullPath().c_str())){
            missingDataList[key]=b;
            if (!silentlycorrect)
               wxLogWarning(_("Missing data file: (%s.au)"),
                            key.c_str());
         }
      }
      i++;
   }
   
   // First, pop the log so the user can see what be up.
   if(forceerror ||
      (!orphanList.IsEmpty() ||
      !missingAliasList.empty() ||
      !missingDataList.empty() ||
      !missingSummaryList.empty()) && !silentlycorrect){

      wxLogWarning(_("Project check found inconsistencies inspecting the loaded project data;\nclick 'Details' for a complete list of errors, or 'OK' to proceed to more options."));
      
      wxLog::GetActiveTarget()->Flush(); // Flush is both modal
      // (desired) and will clear the log (desired)
   }

   // report, take action
   // If in "silently correct" mode, leave orphaned blockfiles alone
   // (they will be deleted when project is saved the first time)
   if(!orphanList.IsEmpty() && !silentlycorrect){

      wxString promptA =
         _("Project check found %d orphaned blockfile[s]. These files are\nunused and probably left over from a crash or some other bug.\nThey should be deleted to avoid disk contention.");
      wxString prompt;
      
      prompt.Printf(promptA,(int)orphanList.GetCount());
      
      const wxChar *buttons[]={_("Delete orphaned files [safe and recommended]"),
                               _("Continue without deleting; silently work around the extra files"),
                               _("Close project immediately with no changes"),NULL};
      int action = ShowMultiDialog(prompt,
                                   _("Warning"),
                                   buttons);

      if(action==2)return (ret | FSCKstatus_CLOSEREQ);

      if(action==0){
         ret |= FSCKstatus_CHANGED;
         for(ndx=0;ndx<(int)orphanList.GetCount();ndx++){
            wxRemoveFile(orphanList[ndx]);
         }
      }
   }


   // Deal with any missing aliases
   if(!missingAliasList.empty()){
      int action;
      
      if (silentlycorrect)
      {
         // In "silently correct" mode, we always create silent blocks. This
         // makes sure the project is complete even if we open it again.
         action = 0;
      } else
      {
         wxString promptA =
            _("Project check detected %d input file[s] being used in place\n('alias files') are now missing.  There is no way for Audacity\nto recover these files automatically; you may choose to\npermanently fill in silence for the missing files, temporarily\nfill in silence for this session only, or close the project now\nand try to restore the missing files by hand.");
         wxString prompt;
      
         prompt.Printf(promptA,missingAliasFiles.size());
      
         const wxChar *buttons[]={_("Replace missing data with silence [permanent upon save]"),
                                  _("Temporarily replace missing data with silence [this session only]"),
                                  _("Close project immediately with no further changes"),NULL};
         action = ShowMultiDialog(prompt,
                                      _("Warning"),
                                      buttons);

         if(action==2)return (ret | FSCKstatus_CLOSEREQ);
      }

      BlockHash::iterator i=missingAliasList.begin();
      while(i != missingAliasList.end()) {
         AliasBlockFile *b = (AliasBlockFile *)i->second; //this is
         //safe, we checked that it's an alias block file earlier
         
         if(action==0){
            // silence the blockfiles by yanking the filename
            wxFileName dummy;
            dummy.Clear();
            b->ChangeAliasedFile(dummy);
            b->Recover();
            ret |= FSCKstatus_CHANGED;
         }else if(action==1){
            // silence the log for this session
            b->SilenceAliasLog();
         }
         i++;
      }
   }

   // Summary regeneration must happen after alias checking.
   if(!missingSummaryList.empty()){
      int action;
      
      if (silentlycorrect)
      {
         // In "silently correct" mode we just recreate the summary files
         action = 0;
      } else
      {
         wxString promptA =
            _("Project check detected %d missing summary file[s] (.auf).\nAudacity can fully regenerate these summary files from the\noriginal audio data in the project.");
         wxString prompt;
      
         prompt.Printf(promptA,missingSummaryList.size());
      
         const wxChar *buttons[]={_("Regenerate summary files [safe and recommended]"),
                                 _("Fill in silence for missing display data [this session only]"),
                                  _("Close project immediately with no further changes"),NULL};
         action = ShowMultiDialog(prompt,
                                      _("Warning"),
                                      buttons);
                                      
         if(action==2)return (ret | FSCKstatus_CLOSEREQ);
      }
      
      BlockHash::iterator i=missingSummaryList.begin();
      while(i != missingSummaryList.end()) {
         BlockFile *b = i->second;
         if(action==0){
            //regenerate from data
            b->Recover();
            ret |= FSCKstatus_CHANGED;
         }else if (action==1){
            b->SilenceLog();
         }
         i++;
      }
   }

   // Deal with any missing SimpleBlockFiles
   if(!missingDataList.empty()){

      int action;
      
      if (silentlycorrect)
      {
         // In "silently correct" mode, we always create silent blocks. This
         // makes sure the project is complete even if we open it again.
         action = 0;
      } else
      {
         wxString promptA =
            _("Project check detected %d missing audio data blockfile[s] (.au), \nprobably due to a bug, system crash or accidental deletion.\nThere is no way for Audacity to recover this lost data\nautomatically; you may choose to permanently fill in silence\nfor the missing data, temporarily fill in silence for this\nsession only, or close the project now and try to restore the\nmissing data by hand.");
         wxString prompt;
      
         prompt.Printf(promptA,missingDataList.size());
      
         const wxChar *buttons[]={_("Replace missing data with silence [permanent immediately]"),
                                  _("Temporarily replace missing data with silence [this session only]"),
                                 _("Close project immediately with no further changes"),NULL};
         action = ShowMultiDialog(prompt,
                                      _("Warning"),
                                      buttons);
      
         if(action==2)return (ret | FSCKstatus_CLOSEREQ);
      }
      
      BlockHash::iterator i=missingDataList.begin();
      while(i != missingDataList.end()) {
         BlockFile *b = i->second;
         if(action==0){
            //regenerate with zeroes
            b->Recover();
            ret |= FSCKstatus_CHANGED;
         }else if(action==1){
            b->SilenceLog();
         }
         i++;
      }
   }

   // clean up any empty directories
   fnameList.Clear();
   rm_dash_rf_enumerate_prompt((projFull != wxT("")? projFull: mytemp),
                               fnameList,wxEmptyString,0,1,blockcount,
                               _("Cleaning up unused directories in project data..."));
   rm_dash_rf_execute(fnameList,0,0,1,0);


   return ret;
}