diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index 56a9c9d07..8236d12cf 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -813,24 +813,8 @@ bool AudacityApp::MRUOpen(const FilePath &fullPathStr) { if (ProjectFileManager::IsAlreadyOpen(fullPathStr)) return false; - // DMM: If the project is dirty, that means it's been touched at - // all, and it's not safe to open a NEW project directly in its - // place. Only if the project is brand-NEW clean and the user - // hasn't done any action at all is it safe for Open to take place - // inside the current project. - // - // If you try to Open a NEW project inside the current window when - // there are no tracks, but there's an Undo history, etc, then - // bad things can happen, including data files moving to the NEW - // project directory, etc. - if (proj && ( - ProjectHistory::Get( *proj ).GetDirty() || - !TrackList::Get( *proj ).empty() - ) ) + if (proj && !ProjectManager::SafeToOpenProjectInto(*proj)) proj = nullptr; - // This project is clean; it's never been touched. Therefore - // all relevant member variables are in their initial state, - // and it's okay to open a NEW project inside this window. ( void ) ProjectManager::OpenProject( proj, fullPathStr ); } else { diff --git a/src/ProjectManager.cpp b/src/ProjectManager.cpp index 91648edf6..d5b5a4c17 100644 --- a/src/ProjectManager.cpp +++ b/src/ProjectManager.cpp @@ -871,29 +871,35 @@ void ProjectManager::OpenFiles(AudacityProject *proj) if (ProjectFileManager::IsAlreadyOpen(fileName)) continue; // Skip ones that are already open. - // DMM: If the project is dirty, that means it's been touched at - // all, and it's not safe to open a NEW project directly in its - // place. Only if the project is brand-NEW clean and the user - // hasn't done any action at all is it safe for Open to take place - // inside the current project. - // - // If you try to Open a NEW project inside the current window when - // there are no tracks, but there's an Undo history, etc, then - // bad things can happen, including data files moving to the NEW - // project directory, etc. - if ( proj && ( - ProjectHistory::Get( *proj ).GetDirty() || - !TrackList::Get( *proj ).empty() - ) ) + if (proj && !SafeToOpenProjectInto(*proj)) proj = nullptr; - - // This project is clean; it's never been touched. Therefore - // all relevant member variables are in their initial state, - // and it's okay to open a NEW project inside this window. proj = OpenProject( proj, fileName ); } } +bool ProjectManager::SafeToOpenProjectInto(AudacityProject &proj) +{ + // DMM: If the project is dirty, that means it's been touched at + // all, and it's not safe to open a fresh project directly in its + // place. Only if the project is brandnew clean and the user + // hasn't done any action at all is it safe for Open to take place + // inside the current project. + // + // If you try to Open a fresh project inside the current window when + // there are no tracks, but there's an Undo history, etc, then + // bad things can happen, including orphan blocks, or tracks + // referring to non-existent blocks + if ( + ProjectHistory::Get( proj ).GetDirty() || + !TrackList::Get( proj ).empty() + ) + return false; + // This project is clean; it's never been touched. Therefore + // all relevant member variables are in their initial state, + // and it's okay to open a NEW project inside its window. + return true; +} + AudacityProject *ProjectManager::OpenProject( AudacityProject *pProject, const FilePath &fileNameArg, bool addtohistory) { diff --git a/src/ProjectManager.h b/src/ProjectManager.h index 35d675773..f635f4388 100644 --- a/src/ProjectManager.h +++ b/src/ProjectManager.h @@ -45,6 +45,9 @@ public: // reason remains in this class, not in ProjectFileManager static void OpenFiles(AudacityProject *proj); + //! False when it is unsafe to overwrite proj with contents of an .aup3 file + static bool SafeToOpenProjectInto(AudacityProject &proj); + // Return the given project if that is not NULL, else create a project. // Then open the given project path. // But if an exception escapes this function, create no NEW project.