1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-22 07:10:06 +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 "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;
}

View File

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

View File

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