1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-31 16:09:28 +02:00

Bug1811: Don't corrupt the project when saving-as to its own path...

... And fixes for confusing logic in the save and save-as routines
This commit is contained in:
Paul Licameli 2018-01-16 20:07:21 -05:00
commit 94827eaa45
3 changed files with 54 additions and 42 deletions

View File

@ -29,7 +29,6 @@
class wxHashTable; class wxHashTable;
class BlockArray; class BlockArray;
class BlockFile; class BlockFile;
class SequenceTest;
#define FSCKstatus_CLOSE_REQ 0x1 #define FSCKstatus_CLOSE_REQ 0x1
#define FSCKstatus_CHANGED 0x2 #define FSCKstatus_CHANGED 0x2
@ -232,8 +231,6 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
wxString mytemp; wxString mytemp;
static int numDirManagers; static int numDirManagers;
static bool dontDeleteTempFiles; static bool dontDeleteTempFiles;
friend class SequenceTest;
}; };
#endif #endif

View File

@ -3661,7 +3661,7 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCompressed)
// then the file has been saved. This is not neccessarily true when // then the file has been saved. This is not neccessarily true when
// autosaving as it gets set by AddImportedTracks (presumably as a proposal). // autosaving as it gets set by AddImportedTracks (presumably as a proposal).
// I don't think that mDirManager.projName gets set without a save so check that. // I don't think that mDirManager.projName gets set without a save so check that.
if( mDirManager->GetProjectName() == wxT("") ) if( !IsProjectSaved() )
projName = wxT("_data"); projName = wxT("_data");
} }
@ -3769,16 +3769,27 @@ private:
}; };
#endif #endif
bool AudacityProject::Save(bool overwrite /* = true */ , bool AudacityProject::Save()
bool fromSaveAs /* = false */, {
bool bWantSaveCompressed /*= false*/) if ( !IsProjectSaved() )
return SaveAs();
return DoSave(false, false);
}
// Assumes AudacityProject::mFileName has been set to the desired path.
bool AudacityProject::DoSave
(const bool fromSaveAs, const bool bWantSaveCompressed)
{ {
// See explanation above // See explanation above
// ProjectDisabler disabler(this); // ProjectDisabler disabler(this);
if (bWantSaveCompressed) if (bWantSaveCompressed)
wxASSERT(fromSaveAs); wxASSERT(fromSaveAs);
else
// Some confirmation dialogs
if (!bWantSaveCompressed)
{ {
TrackListIterator iter(GetTracks()); TrackListIterator iter(GetTracks());
bool bHasTracks = (iter.First() != NULL); bool bHasTracks = (iter.First() != NULL);
@ -3793,9 +3804,6 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
} }
} }
if (!fromSaveAs && mDirManager->GetProjectName() == wxT(""))
return SaveAs();
// If the user has recently imported dependencies, show // If the user has recently imported dependencies, show
// a dialog where the user can see audio files that are // a dialog where the user can see audio files that are
// aliased by this project. The user may make the project // aliased by this project. The user may make the project
@ -3808,6 +3816,7 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
mImportedDependencies = false; // do not show again mImportedDependencies = false; // do not show again
} }
} }
// End of confirmations
// //
// Always save a backup of the original project file // Always save a backup of the original project file
@ -3863,7 +3872,7 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
mStrOtherNamesArray.clear(); mStrOtherNamesArray.clear();
} ); } );
if (fromSaveAs || mDirManager->GetProjectName() == wxT("")) { if (fromSaveAs) {
// This block of code is duplicated in WriteXML, for now... // This block of code is duplicated in WriteXML, for now...
project = mFileName; project = mFileName;
if (project.Len() > 4 && project.Mid(project.Len() - 4) == wxT(".aup")) if (project.Len() > 4 && project.Mid(project.Len() - 4) == wxT(".aup"))
@ -3920,35 +3929,32 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
if (!success) if (!success)
return false; return false;
if (fromSaveAs || mDirManager->GetProjectName() == wxT("")) { if (fromSaveAs && !bWantSaveCompressed) {
if (!bWantSaveCompressed) // We are about to move files from the current directory to
{ // the NEW directory. We need to make sure files that belonged
// We are about to move files from the current directory to // to the last saved project don't get erased, so we "lock" them, so that
// the NEW directory. We need to make sure files that belonged // SetProject() copies instead of moves the files.
// to the last saved project don't get erased, so we "lock" them, so that // (Otherwise the NEW project would be fine, but the old one would
// SetProject() copies instead of moves the files. // be empty of all of its files.)
// (Otherwise the NEW project would be fine, but the old one would
// be empty of all of its files.)
std::vector<movable_ptr<WaveTrack::Locker>> lockers; std::vector<movable_ptr<WaveTrack::Locker>> lockers;
if (mLastSavedTracks && !overwrite) { if (mLastSavedTracks) {
lockers.reserve(mLastSavedTracks->size()); lockers.reserve(mLastSavedTracks->size());
TrackListIterator iter(mLastSavedTracks.get()); TrackListIterator iter(mLastSavedTracks.get());
Track *t = iter.First(); Track *t = iter.First();
while (t) { while (t) {
if (t->GetKind() == Track::Wave) if (t->GetKind() == Track::Wave)
lockers.push_back( lockers.push_back(
make_movable<WaveTrack::Locker>( make_movable<WaveTrack::Locker>(
static_cast<const WaveTrack*>(t))); static_cast<const WaveTrack*>(t)));
t = iter.Next(); t = iter.Next();
}
} }
// This renames the project directory, and moves or copies
// all of our block files over.
success = mDirManager->SetProject(projPath, projName, !overwrite);
} }
// This renames the project directory, and moves or copies
// all of our block files over.
success = mDirManager->SetProject(projPath, projName, true);
if (!success) if (!success)
return false; return false;
} }
@ -4206,7 +4212,7 @@ AudacityProject::AddImportedTracks(const wxString &fileName,
wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI | wxEVT_CATEGORY_USER_INPUT); wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI | wxEVT_CATEGORY_USER_INPUT);
#endif #endif
if (initiallyEmpty && mDirManager->GetProjectName() == wxT("")) { if (initiallyEmpty && !IsProjectSaved() ) {
wxString name = fileName.AfterLast(wxFILE_SEP_PATH).BeforeLast(wxT('.')); wxString name = fileName.AfterLast(wxFILE_SEP_PATH).BeforeLast(wxT('.'));
mFileName =::wxPathOnly(fileName) + wxFILE_SEP_PATH + name + wxT(".aup"); mFileName =::wxPathOnly(fileName) + wxFILE_SEP_PATH + name + wxT(".aup");
mbLoadedFromAup = false; mbLoadedFromAup = false;
@ -4304,6 +4310,8 @@ bool AudacityProject::Import(const wxString &fileName, WaveTrackArray* pTrackArr
bool AudacityProject::SaveAs(const wxString & newFileName, bool bWantSaveCompressed /*= false*/, bool addToHistory /*= true*/) bool AudacityProject::SaveAs(const wxString & newFileName, bool bWantSaveCompressed /*= false*/, bool addToHistory /*= true*/)
{ {
// This version of SaveAs is invoked only from scripting and does not
// prompt for a file name
wxString oldFileName = mFileName; wxString oldFileName = mFileName;
bool bOwnsNewAupName = mbLoadedFromAup && (mFileName==newFileName); bool bOwnsNewAupName = mbLoadedFromAup && (mFileName==newFileName);
@ -4331,7 +4339,7 @@ bool AudacityProject::SaveAs(const wxString & newFileName, bool bWantSaveCompres
//Don't change the title, unless we succeed. //Don't change the title, unless we succeed.
//SetProjectTitle(); //SetProjectTitle();
success = Save(false, true, bWantSaveCompressed); success = DoSave(!bOwnsNewAupName || bWantSaveCompressed, bWantSaveCompressed);
if (success && addToHistory) { if (success && addToHistory) {
wxGetApp().AddFileToHistory(mFileName); wxGetApp().AddFileToHistory(mFileName);
@ -4430,7 +4438,7 @@ For an audio file that will open in other apps, use 'Export'.\n"),
mFileName = oldFileName; mFileName = oldFileName;
} ); } );
success = Save(false, true, bWantSaveCompressed); success = DoSave(!bOwnsNewAupName || bWantSaveCompressed, bWantSaveCompressed);
if (success) { if (success) {
wxGetApp().AddFileToHistory(mFileName); wxGetApp().AddFileToHistory(mFileName);
@ -5785,6 +5793,9 @@ int AudacityProject::GetOpenProjectCount() {
} }
bool AudacityProject::IsProjectSaved() { bool AudacityProject::IsProjectSaved() {
// This is true if a project was opened from an .aup
// Otherwise it becomes true only when a project is first saved successfully
// in DirManager::SetProject
wxString sProjectName = mDirManager->GetProjectName(); wxString sProjectName = mDirManager->GetProjectName();
return (sProjectName != wxT("")); return (sProjectName != wxT(""));
} }
@ -5817,7 +5828,7 @@ bool AudacityProject::SaveFromTimerRecording(wxFileName fnFile) {
mFileName = sOldFilename; mFileName = sOldFilename;
} ); } );
bSuccess = Save(false, true, false); bSuccess = DoSave(true, false);
if (bSuccess) { if (bSuccess) {
wxGetApp().AddFileToHistory(mFileName); wxGetApp().AddFileToHistory(mFileName);

View File

@ -272,12 +272,16 @@ public:
AddImportedTracks(const wxString &fileName, AddImportedTracks(const wxString &fileName,
TrackHolders &&newTracks); TrackHolders &&newTracks);
bool Save(bool overwrite = true, bool fromSaveAs = false, bool bWantSaveCompressed = false); bool Save();
bool SaveAs(bool bWantSaveCompressed = false); bool SaveAs(bool bWantSaveCompressed = false);
bool SaveAs(const wxString & newFileName, bool bWantSaveCompressed = false, bool addToHistory = true); bool SaveAs(const wxString & newFileName, bool bWantSaveCompressed = false, bool addToHistory = true);
#ifdef USE_LIBVORBIS #ifdef USE_LIBVORBIS
bool SaveCompressedWaveTracks(const wxString & strProjectPathName); // full path for aup except extension bool SaveCompressedWaveTracks(const wxString & strProjectPathName); // full path for aup except extension
#endif #endif
private:
bool DoSave(bool fromSaveAs, bool bWantSaveCompressed);
public:
void Clear(); void Clear();
const wxString &GetFileName() { return mFileName; } const wxString &GetFileName() { return mFileName; }