mirror of
				https://github.com/cookiengineer/audacity
				synced 2025-11-03 23:53:55 +01:00 
			
		
		
		
	Redo AliasedFile using wxFileNameWrapper.
This commit is contained in:
		@@ -42,12 +42,6 @@
 | 
			
		||||
#include "WaveTrack.h"
 | 
			
		||||
#include "WaveClip.h"
 | 
			
		||||
 | 
			
		||||
// Note, this #include must occur here, not up with the others!
 | 
			
		||||
// It must be between the WX_DECLARE_OBJARRAY and WX_DEFINE_OBJARRAY.
 | 
			
		||||
#include <wx/arrimpl.cpp>
 | 
			
		||||
 | 
			
		||||
WX_DEFINE_OBJARRAY( AliasedFileArray );
 | 
			
		||||
 | 
			
		||||
WX_DECLARE_HASH_MAP(wxString, AliasedFile *,
 | 
			
		||||
                    wxStringHash, wxStringEqual, AliasedFileHash);
 | 
			
		||||
 | 
			
		||||
@@ -111,7 +105,7 @@ static void ReplaceBlockFiles(AudacityProject *project,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FindDependencies(AudacityProject *project,
 | 
			
		||||
                      AliasedFileArray *outAliasedFiles)
 | 
			
		||||
                      AliasedFileArray &outAliasedFiles)
 | 
			
		||||
{
 | 
			
		||||
   sampleFormat format = project->GetDefaultFormat();
 | 
			
		||||
 | 
			
		||||
@@ -121,15 +115,14 @@ void FindDependencies(AudacityProject *project,
 | 
			
		||||
   AliasedFileHash aliasedFileHash;
 | 
			
		||||
   BoolBlockFileHash blockFileHash;
 | 
			
		||||
 | 
			
		||||
   int i;
 | 
			
		||||
   for (i = 0; i < (int)blocks.size(); i++) {
 | 
			
		||||
      BlockFile *f = blocks[i]->f;
 | 
			
		||||
   for (const auto &blockFile : blocks) {
 | 
			
		||||
      BlockFile *f = blockFile->f;
 | 
			
		||||
      if (f->IsAlias() && (blockFileHash.count(f) == 0))
 | 
			
		||||
      {
 | 
			
		||||
         // f is an alias block we have not yet counted.
 | 
			
		||||
         blockFileHash[f] = true; // Don't count the same blockfile twice.
 | 
			
		||||
         AliasBlockFile *aliasBlockFile = (AliasBlockFile *)f;
 | 
			
		||||
         wxFileName fileName = aliasBlockFile->GetAliasedFileName();
 | 
			
		||||
         AliasBlockFile *aliasBlockFile = static_cast<AliasBlockFile*>(f);
 | 
			
		||||
         const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
 | 
			
		||||
 | 
			
		||||
         // In DirManager::ProjectFSCK(), if the user has chosen to
 | 
			
		||||
         // "Replace missing audio with silence", the code there puts in an empty wxFileName.
 | 
			
		||||
@@ -137,7 +130,7 @@ void FindDependencies(AudacityProject *project,
 | 
			
		||||
         if (!fileName.IsOk())
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
         wxString fileNameStr = fileName.GetFullPath();
 | 
			
		||||
         const wxString &fileNameStr = fileName.GetFullPath();
 | 
			
		||||
         int blockBytes = (SAMPLE_SIZE(format) *
 | 
			
		||||
                           aliasBlockFile->GetLength());
 | 
			
		||||
         if (aliasedFileHash.count(fileNameStr) > 0)
 | 
			
		||||
@@ -148,11 +141,16 @@ void FindDependencies(AudacityProject *project,
 | 
			
		||||
         {
 | 
			
		||||
            // Haven't counted this AliasBlockFile yet.
 | 
			
		||||
            // Add to return array and internal hash.
 | 
			
		||||
            outAliasedFiles->Add(AliasedFile(fileName,
 | 
			
		||||
                                             blockBytes,
 | 
			
		||||
                                             fileName.FileExists()));
 | 
			
		||||
            aliasedFileHash[fileNameStr] =
 | 
			
		||||
               &((*outAliasedFiles)[outAliasedFiles->GetCount()-1]);
 | 
			
		||||
 | 
			
		||||
            // PRL: do this in two steps so that we move instead of copying.
 | 
			
		||||
            // We don't have a moving push_back in all compilers.
 | 
			
		||||
            outAliasedFiles.push_back(AliasedFile{});
 | 
			
		||||
            outAliasedFiles.back() =
 | 
			
		||||
               AliasedFile {
 | 
			
		||||
                  wxFileNameWrapper { fileName },
 | 
			
		||||
                  blockBytes, fileName.FileExists()
 | 
			
		||||
               };
 | 
			
		||||
            aliasedFileHash[fileNameStr] = &outAliasedFiles.back();
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
@@ -162,7 +160,7 @@ void FindDependencies(AudacityProject *project,
 | 
			
		||||
// longer be external dependencies (selected by the user), replace
 | 
			
		||||
// all of those alias block files with disk block files.
 | 
			
		||||
static void RemoveDependencies(AudacityProject *project,
 | 
			
		||||
                                 AliasedFileArray *aliasedFiles)
 | 
			
		||||
                               AliasedFileArray &aliasedFiles)
 | 
			
		||||
{
 | 
			
		||||
   DirManager *dirManager = project->GetDirManager();
 | 
			
		||||
 | 
			
		||||
@@ -175,11 +173,10 @@ static void RemoveDependencies(AudacityProject *project,
 | 
			
		||||
   // count total number of bytes to process.
 | 
			
		||||
   AliasedFileHash aliasedFileHash;
 | 
			
		||||
   wxLongLong totalBytesToProcess = 0;
 | 
			
		||||
   unsigned int i;
 | 
			
		||||
   for (i = 0; i < aliasedFiles->GetCount(); i++) {
 | 
			
		||||
      totalBytesToProcess += aliasedFiles->Item(i).mByteCount;
 | 
			
		||||
      wxString fileNameStr = aliasedFiles->Item(i).mFileName.GetFullPath();
 | 
			
		||||
      aliasedFileHash[fileNameStr] = &aliasedFiles->Item(i);
 | 
			
		||||
   for (auto &aliasedFile : aliasedFiles) {
 | 
			
		||||
      totalBytesToProcess += aliasedFile.mByteCount;
 | 
			
		||||
      const wxString &fileNameStr = aliasedFile.mFileName.GetFullPath();
 | 
			
		||||
      aliasedFileHash[fileNameStr] = &aliasedFile;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   BlockPtrArray blocks;
 | 
			
		||||
@@ -188,14 +185,14 @@ static void RemoveDependencies(AudacityProject *project,
 | 
			
		||||
   const sampleFormat format = project->GetDefaultFormat();
 | 
			
		||||
   ReplacedBlockFileHash blockFileHash;
 | 
			
		||||
   wxLongLong completedBytes = 0;
 | 
			
		||||
   for (i = 0; i < blocks.size(); i++) {
 | 
			
		||||
      BlockFile *f = blocks[i]->f;
 | 
			
		||||
   for (const auto blockFile : blocks) {
 | 
			
		||||
      BlockFile *f = blockFile->f;
 | 
			
		||||
      if (f->IsAlias() && (blockFileHash.count(f) == 0))
 | 
			
		||||
      {
 | 
			
		||||
         // f is an alias block we have not yet processed.
 | 
			
		||||
         AliasBlockFile *aliasBlockFile = (AliasBlockFile *)f;
 | 
			
		||||
         wxFileName fileName = aliasBlockFile->GetAliasedFileName();
 | 
			
		||||
         wxString fileNameStr = fileName.GetFullPath();
 | 
			
		||||
         AliasBlockFile *aliasBlockFile = static_cast<AliasBlockFile*>(f);
 | 
			
		||||
         const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
 | 
			
		||||
         const wxString &fileNameStr = fileName.GetFullPath();
 | 
			
		||||
 | 
			
		||||
         if (aliasedFileHash.count(fileNameStr) == 0)
 | 
			
		||||
            // This aliased file was not selected to be replaced. Skip it.
 | 
			
		||||
@@ -230,12 +227,8 @@ static void RemoveDependencies(AudacityProject *project,
 | 
			
		||||
 | 
			
		||||
   // Subtract one from reference count of NEW block files; they're
 | 
			
		||||
   // now all referenced the proper number of times by the Sequences
 | 
			
		||||
   ReplacedBlockFileHash::iterator it;
 | 
			
		||||
   for( it = blockFileHash.begin(); it != blockFileHash.end(); ++it )
 | 
			
		||||
   {
 | 
			
		||||
      BlockFile *f = it->second;
 | 
			
		||||
      dirManager->Deref(f);
 | 
			
		||||
   }
 | 
			
		||||
   for (const auto &pair : blockFileHash)
 | 
			
		||||
      dirManager->Deref(pair.second);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
@@ -248,7 +241,7 @@ public:
 | 
			
		||||
   DependencyDialog(wxWindow *parent,
 | 
			
		||||
                    wxWindowID id,
 | 
			
		||||
                    AudacityProject *project,
 | 
			
		||||
                    AliasedFileArray *aliasedFiles,
 | 
			
		||||
                    AliasedFileArray &aliasedFiles,
 | 
			
		||||
                    bool isSaving);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -267,7 +260,7 @@ private:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   AudacityProject  *mProject;
 | 
			
		||||
   AliasedFileArray *mAliasedFiles;
 | 
			
		||||
   AliasedFileArray &mAliasedFiles;
 | 
			
		||||
   bool              mIsSaving;
 | 
			
		||||
   bool              mHasMissingFiles;
 | 
			
		||||
   bool              mHasNonMissingFiles;
 | 
			
		||||
@@ -301,7 +294,7 @@ END_EVENT_TABLE()
 | 
			
		||||
DependencyDialog::DependencyDialog(wxWindow *parent,
 | 
			
		||||
                                   wxWindowID id,
 | 
			
		||||
                                   AudacityProject *project,
 | 
			
		||||
                                   AliasedFileArray *aliasedFiles,
 | 
			
		||||
                                   AliasedFileArray &aliasedFiles,
 | 
			
		||||
                                   bool isSaving)
 | 
			
		||||
: wxDialog(parent, id, _("Project Depends on Other Audio Files"),
 | 
			
		||||
            wxDefaultPosition, wxDefaultSize,
 | 
			
		||||
@@ -413,10 +406,10 @@ void DependencyDialog::PopulateList()
 | 
			
		||||
   mHasMissingFiles = false;
 | 
			
		||||
   mHasNonMissingFiles = false;
 | 
			
		||||
   unsigned int i;
 | 
			
		||||
   for (i = 0; i < mAliasedFiles->GetCount(); i++) {
 | 
			
		||||
      wxFileName fileName = mAliasedFiles->Item(i).mFileName;
 | 
			
		||||
      wxLongLong byteCount = (mAliasedFiles->Item(i).mByteCount * 124) / 100;
 | 
			
		||||
      bool bOriginalExists = mAliasedFiles->Item(i).mbOriginalExists;
 | 
			
		||||
   for (const auto &aliasedFile : mAliasedFiles) {
 | 
			
		||||
      const wxFileName &fileName = aliasedFile.mFileName;
 | 
			
		||||
      wxLongLong byteCount = (aliasedFile.mByteCount * 124) / 100;
 | 
			
		||||
      bool bOriginalExists = aliasedFile.mbOriginalExists;
 | 
			
		||||
 | 
			
		||||
      if (bOriginalExists)
 | 
			
		||||
      {
 | 
			
		||||
@@ -490,19 +483,23 @@ void DependencyDialog::OnCopySelectedFiles(wxCommandEvent & WXUNUSED(event))
 | 
			
		||||
{
 | 
			
		||||
   AliasedFileArray aliasedFilesToDelete;
 | 
			
		||||
 | 
			
		||||
   int i;
 | 
			
		||||
   // Count backwards so we can remove as we go
 | 
			
		||||
   for(i=(int)mAliasedFiles->GetCount()-1; i>=0; i--) {
 | 
			
		||||
   long i = 0;
 | 
			
		||||
   for(auto iter = mAliasedFiles.begin(); iter != mAliasedFiles.end();) {
 | 
			
		||||
      if (mFileListCtrl->GetItemState(i, wxLIST_STATE_SELECTED)) {
 | 
			
		||||
         aliasedFilesToDelete.Add(mAliasedFiles->Item(i));
 | 
			
		||||
         mAliasedFiles->RemoveAt(i);
 | 
			
		||||
         // Two-step move could be simplified when all compilers have C++11 vector
 | 
			
		||||
         aliasedFilesToDelete.push_back(AliasedFile{});
 | 
			
		||||
         aliasedFilesToDelete.back() = std::move(*iter);
 | 
			
		||||
         iter = mAliasedFiles.erase(iter);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
         ++iter;
 | 
			
		||||
      ++i;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   RemoveDependencies(mProject, &aliasedFilesToDelete);
 | 
			
		||||
   RemoveDependencies(mProject, aliasedFilesToDelete);
 | 
			
		||||
   PopulateList();
 | 
			
		||||
 | 
			
		||||
   if ((mAliasedFiles->GetCount() == 0) || !mHasNonMissingFiles)
 | 
			
		||||
   if (mAliasedFiles.empty() || !mHasNonMissingFiles)
 | 
			
		||||
   {
 | 
			
		||||
      SaveFutureActionChoice();
 | 
			
		||||
      EndModal(wxID_NO);  // Don't need to remove dependencies
 | 
			
		||||
@@ -548,9 +545,9 @@ bool ShowDependencyDialogIfNeeded(AudacityProject *project,
 | 
			
		||||
                                  bool isSaving)
 | 
			
		||||
{
 | 
			
		||||
   AliasedFileArray aliasedFiles;
 | 
			
		||||
   FindDependencies(project, &aliasedFiles);
 | 
			
		||||
   FindDependencies(project, aliasedFiles);
 | 
			
		||||
 | 
			
		||||
   if (aliasedFiles.GetCount() == 0) {
 | 
			
		||||
   if (aliasedFiles.empty()) {
 | 
			
		||||
      if (!isSaving)
 | 
			
		||||
      {
 | 
			
		||||
         wxString msg =
 | 
			
		||||
@@ -575,7 +572,7 @@ you may lose data.");
 | 
			
		||||
      if (action == wxT("copy"))
 | 
			
		||||
      {
 | 
			
		||||
         // User always wants to remove dependencies
 | 
			
		||||
         RemoveDependencies(project, &aliasedFiles);
 | 
			
		||||
         RemoveDependencies(project, aliasedFiles);
 | 
			
		||||
         return true;
 | 
			
		||||
      }
 | 
			
		||||
      if (action == wxT("never"))
 | 
			
		||||
@@ -583,12 +580,12 @@ you may lose data.");
 | 
			
		||||
         return true;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   DependencyDialog dlog(project, -1, project, &aliasedFiles, isSaving);
 | 
			
		||||
   DependencyDialog dlog(project, -1, project, aliasedFiles, isSaving);
 | 
			
		||||
   int returnCode = dlog.ShowModal();
 | 
			
		||||
   if (returnCode == wxID_CANCEL)
 | 
			
		||||
      return false;
 | 
			
		||||
   else if (returnCode == wxID_YES)
 | 
			
		||||
      RemoveDependencies(project, &aliasedFiles);
 | 
			
		||||
      RemoveDependencies(project, aliasedFiles);
 | 
			
		||||
 | 
			
		||||
   return true;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,26 +14,43 @@
 | 
			
		||||
#ifndef __AUDACITY_DEPENDENCIES__
 | 
			
		||||
#define __AUDACITY_DEPENDENCIES__
 | 
			
		||||
 | 
			
		||||
#include <wx/dynarray.h>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <wx/filename.h>
 | 
			
		||||
#include "MemoryX.h"
 | 
			
		||||
#include "wxFileNameWrapper.h"
 | 
			
		||||
 | 
			
		||||
class AudacityProject;
 | 
			
		||||
 | 
			
		||||
class AliasedFile
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
   AliasedFile(wxFileName fileName, wxLongLong byteCount, bool bOriginalExists)
 | 
			
		||||
   AliasedFile() {}
 | 
			
		||||
   AliasedFile(wxFileNameWrapper &&fileName,
 | 
			
		||||
               wxLongLong byteCount, bool bOriginalExists)
 | 
			
		||||
      : mFileName(std::move(fileName))
 | 
			
		||||
      , mByteCount(byteCount)
 | 
			
		||||
      , mbOriginalExists(bOriginalExists)
 | 
			
		||||
   {
 | 
			
		||||
      mFileName = fileName;
 | 
			
		||||
      mByteCount = byteCount;
 | 
			
		||||
      mbOriginalExists = bOriginalExists;
 | 
			
		||||
   };
 | 
			
		||||
   wxFileName  mFileName;
 | 
			
		||||
   wxLongLong  mByteCount; // if stored as current default sample format
 | 
			
		||||
   bool        mbOriginalExists;
 | 
			
		||||
   }
 | 
			
		||||
   AliasedFile(const AliasedFile &that) = default;
 | 
			
		||||
   AliasedFile &operator= (AliasedFile&& that)
 | 
			
		||||
   {
 | 
			
		||||
      if(this != &that) {
 | 
			
		||||
         mFileName = std::move(that.mFileName);
 | 
			
		||||
         mByteCount = that.mByteCount;
 | 
			
		||||
         mbOriginalExists = that.mbOriginalExists;
 | 
			
		||||
      }
 | 
			
		||||
      return *this;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   wxFileNameWrapper mFileName;
 | 
			
		||||
   wxLongLong  mByteCount{}; // if stored as current default sample format
 | 
			
		||||
   bool        mbOriginalExists{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
WX_DECLARE_OBJARRAY(AliasedFile, AliasedFileArray);
 | 
			
		||||
// use list, not vector, because we need to take addresses of items in the container
 | 
			
		||||
// before it has grown to full size.
 | 
			
		||||
using AliasedFileArray = std::list<AliasedFile>;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Checks for alias block files, modifies the project if the
 | 
			
		||||
@@ -45,6 +62,6 @@ bool ShowDependencyDialogIfNeeded(AudacityProject *project,
 | 
			
		||||
 | 
			
		||||
// Returns a list of aliased files associated with a project.
 | 
			
		||||
void FindDependencies(AudacityProject *project,
 | 
			
		||||
                      AliasedFileArray *outAliasedFiles);
 | 
			
		||||
                      AliasedFileArray &outAliasedFiles);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -630,10 +630,9 @@ bool Exporter::GetFilename()
 | 
			
		||||
      overwritingMissingAlias = false;
 | 
			
		||||
      for (size_t i = 0; i < gAudacityProjects.GetCount(); i++) {
 | 
			
		||||
         AliasedFileArray aliasedFiles;
 | 
			
		||||
         FindDependencies(gAudacityProjects[i], &aliasedFiles);
 | 
			
		||||
         size_t j;
 | 
			
		||||
         for (j = 0; j< aliasedFiles.GetCount(); j++) {
 | 
			
		||||
            if (mFilename.GetFullPath() == aliasedFiles[j].mFileName.GetFullPath() &&
 | 
			
		||||
         FindDependencies(gAudacityProjects[i], aliasedFiles);
 | 
			
		||||
         for (const auto &aliasedFile : aliasedFiles) {
 | 
			
		||||
            if (mFilename.GetFullPath() == aliasedFile.mFileName.GetFullPath() &&
 | 
			
		||||
                !mFilename.FileExists()) {
 | 
			
		||||
               // Warn and return to the dialog
 | 
			
		||||
               wxMessageBox(_("You are attempting to overwrite an aliased file that is missing.\n\
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user