1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-22 15:20:15 +02:00

Redo AliasedFile using wxFileNameWrapper.

This commit is contained in:
Paul Licameli 2016-04-17 02:40:51 -04:00
parent 63140e54d9
commit 87f368f380
3 changed files with 82 additions and 69 deletions

View File

@ -42,12 +42,6 @@
#include "WaveTrack.h" #include "WaveTrack.h"
#include "WaveClip.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 *, WX_DECLARE_HASH_MAP(wxString, AliasedFile *,
wxStringHash, wxStringEqual, AliasedFileHash); wxStringHash, wxStringEqual, AliasedFileHash);
@ -111,7 +105,7 @@ static void ReplaceBlockFiles(AudacityProject *project,
} }
void FindDependencies(AudacityProject *project, void FindDependencies(AudacityProject *project,
AliasedFileArray *outAliasedFiles) AliasedFileArray &outAliasedFiles)
{ {
sampleFormat format = project->GetDefaultFormat(); sampleFormat format = project->GetDefaultFormat();
@ -121,15 +115,14 @@ void FindDependencies(AudacityProject *project,
AliasedFileHash aliasedFileHash; AliasedFileHash aliasedFileHash;
BoolBlockFileHash blockFileHash; BoolBlockFileHash blockFileHash;
int i; for (const auto &blockFile : blocks) {
for (i = 0; i < (int)blocks.size(); i++) { BlockFile *f = blockFile->f;
BlockFile *f = blocks[i]->f;
if (f->IsAlias() && (blockFileHash.count(f) == 0)) if (f->IsAlias() && (blockFileHash.count(f) == 0))
{ {
// f is an alias block we have not yet counted. // f is an alias block we have not yet counted.
blockFileHash[f] = true; // Don't count the same blockfile twice. blockFileHash[f] = true; // Don't count the same blockfile twice.
AliasBlockFile *aliasBlockFile = (AliasBlockFile *)f; AliasBlockFile *aliasBlockFile = static_cast<AliasBlockFile*>(f);
wxFileName fileName = aliasBlockFile->GetAliasedFileName(); const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
// In DirManager::ProjectFSCK(), if the user has chosen to // In DirManager::ProjectFSCK(), if the user has chosen to
// "Replace missing audio with silence", the code there puts in an empty wxFileName. // "Replace missing audio with silence", the code there puts in an empty wxFileName.
@ -137,7 +130,7 @@ void FindDependencies(AudacityProject *project,
if (!fileName.IsOk()) if (!fileName.IsOk())
continue; continue;
wxString fileNameStr = fileName.GetFullPath(); const wxString &fileNameStr = fileName.GetFullPath();
int blockBytes = (SAMPLE_SIZE(format) * int blockBytes = (SAMPLE_SIZE(format) *
aliasBlockFile->GetLength()); aliasBlockFile->GetLength());
if (aliasedFileHash.count(fileNameStr) > 0) if (aliasedFileHash.count(fileNameStr) > 0)
@ -148,11 +141,16 @@ void FindDependencies(AudacityProject *project,
{ {
// Haven't counted this AliasBlockFile yet. // Haven't counted this AliasBlockFile yet.
// Add to return array and internal hash. // Add to return array and internal hash.
outAliasedFiles->Add(AliasedFile(fileName,
blockBytes, // PRL: do this in two steps so that we move instead of copying.
fileName.FileExists())); // We don't have a moving push_back in all compilers.
aliasedFileHash[fileNameStr] = outAliasedFiles.push_back(AliasedFile{});
&((*outAliasedFiles)[outAliasedFiles->GetCount()-1]); 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 // longer be external dependencies (selected by the user), replace
// all of those alias block files with disk block files. // all of those alias block files with disk block files.
static void RemoveDependencies(AudacityProject *project, static void RemoveDependencies(AudacityProject *project,
AliasedFileArray *aliasedFiles) AliasedFileArray &aliasedFiles)
{ {
DirManager *dirManager = project->GetDirManager(); DirManager *dirManager = project->GetDirManager();
@ -175,11 +173,10 @@ static void RemoveDependencies(AudacityProject *project,
// count total number of bytes to process. // count total number of bytes to process.
AliasedFileHash aliasedFileHash; AliasedFileHash aliasedFileHash;
wxLongLong totalBytesToProcess = 0; wxLongLong totalBytesToProcess = 0;
unsigned int i; for (auto &aliasedFile : aliasedFiles) {
for (i = 0; i < aliasedFiles->GetCount(); i++) { totalBytesToProcess += aliasedFile.mByteCount;
totalBytesToProcess += aliasedFiles->Item(i).mByteCount; const wxString &fileNameStr = aliasedFile.mFileName.GetFullPath();
wxString fileNameStr = aliasedFiles->Item(i).mFileName.GetFullPath(); aliasedFileHash[fileNameStr] = &aliasedFile;
aliasedFileHash[fileNameStr] = &aliasedFiles->Item(i);
} }
BlockPtrArray blocks; BlockPtrArray blocks;
@ -188,14 +185,14 @@ static void RemoveDependencies(AudacityProject *project,
const sampleFormat format = project->GetDefaultFormat(); const sampleFormat format = project->GetDefaultFormat();
ReplacedBlockFileHash blockFileHash; ReplacedBlockFileHash blockFileHash;
wxLongLong completedBytes = 0; wxLongLong completedBytes = 0;
for (i = 0; i < blocks.size(); i++) { for (const auto blockFile : blocks) {
BlockFile *f = blocks[i]->f; BlockFile *f = blockFile->f;
if (f->IsAlias() && (blockFileHash.count(f) == 0)) if (f->IsAlias() && (blockFileHash.count(f) == 0))
{ {
// f is an alias block we have not yet processed. // f is an alias block we have not yet processed.
AliasBlockFile *aliasBlockFile = (AliasBlockFile *)f; AliasBlockFile *aliasBlockFile = static_cast<AliasBlockFile*>(f);
wxFileName fileName = aliasBlockFile->GetAliasedFileName(); const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
wxString fileNameStr = fileName.GetFullPath(); const wxString &fileNameStr = fileName.GetFullPath();
if (aliasedFileHash.count(fileNameStr) == 0) if (aliasedFileHash.count(fileNameStr) == 0)
// This aliased file was not selected to be replaced. Skip it. // 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 // Subtract one from reference count of NEW block files; they're
// now all referenced the proper number of times by the Sequences // now all referenced the proper number of times by the Sequences
ReplacedBlockFileHash::iterator it; for (const auto &pair : blockFileHash)
for( it = blockFileHash.begin(); it != blockFileHash.end(); ++it ) dirManager->Deref(pair.second);
{
BlockFile *f = it->second;
dirManager->Deref(f);
}
} }
// //
@ -248,7 +241,7 @@ public:
DependencyDialog(wxWindow *parent, DependencyDialog(wxWindow *parent,
wxWindowID id, wxWindowID id,
AudacityProject *project, AudacityProject *project,
AliasedFileArray *aliasedFiles, AliasedFileArray &aliasedFiles,
bool isSaving); bool isSaving);
private: private:
@ -267,7 +260,7 @@ private:
AudacityProject *mProject; AudacityProject *mProject;
AliasedFileArray *mAliasedFiles; AliasedFileArray &mAliasedFiles;
bool mIsSaving; bool mIsSaving;
bool mHasMissingFiles; bool mHasMissingFiles;
bool mHasNonMissingFiles; bool mHasNonMissingFiles;
@ -301,7 +294,7 @@ END_EVENT_TABLE()
DependencyDialog::DependencyDialog(wxWindow *parent, DependencyDialog::DependencyDialog(wxWindow *parent,
wxWindowID id, wxWindowID id,
AudacityProject *project, AudacityProject *project,
AliasedFileArray *aliasedFiles, AliasedFileArray &aliasedFiles,
bool isSaving) bool isSaving)
: wxDialog(parent, id, _("Project Depends on Other Audio Files"), : wxDialog(parent, id, _("Project Depends on Other Audio Files"),
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
@ -413,10 +406,10 @@ void DependencyDialog::PopulateList()
mHasMissingFiles = false; mHasMissingFiles = false;
mHasNonMissingFiles = false; mHasNonMissingFiles = false;
unsigned int i; unsigned int i;
for (i = 0; i < mAliasedFiles->GetCount(); i++) { for (const auto &aliasedFile : mAliasedFiles) {
wxFileName fileName = mAliasedFiles->Item(i).mFileName; const wxFileName &fileName = aliasedFile.mFileName;
wxLongLong byteCount = (mAliasedFiles->Item(i).mByteCount * 124) / 100; wxLongLong byteCount = (aliasedFile.mByteCount * 124) / 100;
bool bOriginalExists = mAliasedFiles->Item(i).mbOriginalExists; bool bOriginalExists = aliasedFile.mbOriginalExists;
if (bOriginalExists) if (bOriginalExists)
{ {
@ -490,19 +483,23 @@ void DependencyDialog::OnCopySelectedFiles(wxCommandEvent & WXUNUSED(event))
{ {
AliasedFileArray aliasedFilesToDelete; AliasedFileArray aliasedFilesToDelete;
int i; long i = 0;
// Count backwards so we can remove as we go for(auto iter = mAliasedFiles.begin(); iter != mAliasedFiles.end();) {
for(i=(int)mAliasedFiles->GetCount()-1; i>=0; i--) {
if (mFileListCtrl->GetItemState(i, wxLIST_STATE_SELECTED)) { if (mFileListCtrl->GetItemState(i, wxLIST_STATE_SELECTED)) {
aliasedFilesToDelete.Add(mAliasedFiles->Item(i)); // Two-step move could be simplified when all compilers have C++11 vector
mAliasedFiles->RemoveAt(i); aliasedFilesToDelete.push_back(AliasedFile{});
aliasedFilesToDelete.back() = std::move(*iter);
iter = mAliasedFiles.erase(iter);
} }
else
++iter;
++i;
} }
RemoveDependencies(mProject, &aliasedFilesToDelete); RemoveDependencies(mProject, aliasedFilesToDelete);
PopulateList(); PopulateList();
if ((mAliasedFiles->GetCount() == 0) || !mHasNonMissingFiles) if (mAliasedFiles.empty() || !mHasNonMissingFiles)
{ {
SaveFutureActionChoice(); SaveFutureActionChoice();
EndModal(wxID_NO); // Don't need to remove dependencies EndModal(wxID_NO); // Don't need to remove dependencies
@ -548,9 +545,9 @@ bool ShowDependencyDialogIfNeeded(AudacityProject *project,
bool isSaving) bool isSaving)
{ {
AliasedFileArray aliasedFiles; AliasedFileArray aliasedFiles;
FindDependencies(project, &aliasedFiles); FindDependencies(project, aliasedFiles);
if (aliasedFiles.GetCount() == 0) { if (aliasedFiles.empty()) {
if (!isSaving) if (!isSaving)
{ {
wxString msg = wxString msg =
@ -575,7 +572,7 @@ you may lose data.");
if (action == wxT("copy")) if (action == wxT("copy"))
{ {
// User always wants to remove dependencies // User always wants to remove dependencies
RemoveDependencies(project, &aliasedFiles); RemoveDependencies(project, aliasedFiles);
return true; return true;
} }
if (action == wxT("never")) if (action == wxT("never"))
@ -583,12 +580,12 @@ you may lose data.");
return true; return true;
} }
DependencyDialog dlog(project, -1, project, &aliasedFiles, isSaving); DependencyDialog dlog(project, -1, project, aliasedFiles, isSaving);
int returnCode = dlog.ShowModal(); int returnCode = dlog.ShowModal();
if (returnCode == wxID_CANCEL) if (returnCode == wxID_CANCEL)
return false; return false;
else if (returnCode == wxID_YES) else if (returnCode == wxID_YES)
RemoveDependencies(project, &aliasedFiles); RemoveDependencies(project, aliasedFiles);
return true; return true;
} }

View File

@ -14,26 +14,43 @@
#ifndef __AUDACITY_DEPENDENCIES__ #ifndef __AUDACITY_DEPENDENCIES__
#define __AUDACITY_DEPENDENCIES__ #define __AUDACITY_DEPENDENCIES__
#include <wx/dynarray.h> #include <list>
#include <wx/filename.h> #include <wx/filename.h>
#include "MemoryX.h"
#include "wxFileNameWrapper.h"
class AudacityProject; class AudacityProject;
class AliasedFile class AliasedFile
{ {
public: 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; AliasedFile(const AliasedFile &that) = default;
mbOriginalExists = bOriginalExists; AliasedFile &operator= (AliasedFile&& that)
}; {
wxFileName mFileName; if(this != &that) {
wxLongLong mByteCount; // if stored as current default sample format mFileName = std::move(that.mFileName);
bool mbOriginalExists; 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 // 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. // Returns a list of aliased files associated with a project.
void FindDependencies(AudacityProject *project, void FindDependencies(AudacityProject *project,
AliasedFileArray *outAliasedFiles); AliasedFileArray &outAliasedFiles);
#endif #endif

View File

@ -630,10 +630,9 @@ bool Exporter::GetFilename()
overwritingMissingAlias = false; overwritingMissingAlias = false;
for (size_t i = 0; i < gAudacityProjects.GetCount(); i++) { for (size_t i = 0; i < gAudacityProjects.GetCount(); i++) {
AliasedFileArray aliasedFiles; AliasedFileArray aliasedFiles;
FindDependencies(gAudacityProjects[i], &aliasedFiles); FindDependencies(gAudacityProjects[i], aliasedFiles);
size_t j; for (const auto &aliasedFile : aliasedFiles) {
for (j = 0; j< aliasedFiles.GetCount(); j++) { if (mFilename.GetFullPath() == aliasedFile.mFileName.GetFullPath() &&
if (mFilename.GetFullPath() == aliasedFiles[j].mFileName.GetFullPath() &&
!mFilename.FileExists()) { !mFilename.FileExists()) {
// Warn and return to the dialog // Warn and return to the dialog
wxMessageBox(_("You are attempting to overwrite an aliased file that is missing.\n\ wxMessageBox(_("You are attempting to overwrite an aliased file that is missing.\n\