diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index af8e265b2..67675ce9f 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -831,13 +831,12 @@ bool AudacityApp::MRUOpen(const wxString &fullPathStr) { // 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 || proj->GetDirty() || !proj->GetIsEmpty()) { - proj = CreateNewAudacityProject(); - } + if (proj && (proj->GetDirty() || !proj->GetIsEmpty())) + 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->OpenFile(fullPathStr); + AudacityProject::OpenProject( proj, fullPathStr ); } else { // File doesn't exist - remove file from history diff --git a/src/AutoRecovery.cpp b/src/AutoRecovery.cpp index 2e0d452b1..9c6652227 100644 --- a/src/AutoRecovery.cpp +++ b/src/AutoRecovery.cpp @@ -198,7 +198,6 @@ static bool RecoverAllProjects(AudacityProject** pproj) // Open a project window for each auto save file wxString filename; - AudacityProject* proj = NULL; wxArrayString files; wxDir::GetAllFiles(FileNames::AutoSaveDir(), &files, @@ -206,21 +205,18 @@ static bool RecoverAllProjects(AudacityProject** pproj) for (unsigned int i = 0; i < files.GetCount(); i++) { + AudacityProject* proj{}; if (*pproj) { // Reuse existing project window proj = *pproj; *pproj = NULL; - } else - { - // Create NEW project window - proj = CreateNewAudacityProject(); } // Open project. When an auto-save file has been opened successfully, // the opened auto-save file is automatically deleted and a NEW one // is created. - proj->OpenFile(files[i], false); + AudacityProject::OpenProject( proj, files[i], false ); } return true; diff --git a/src/Menus.cpp b/src/Menus.cpp index 6a534808e..956b73b0e 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -5865,26 +5865,36 @@ void AudacityProject::OnImportMIDI() gPrefs->Write(wxT("/DefaultOpenPath"), path); gPrefs->Flush(); - DoImportMIDI(fileName); + AudacityProject::DoImportMIDI(this, fileName); } } -void AudacityProject::DoImportMIDI(const wxString &fileName) +AudacityProject *AudacityProject::DoImportMIDI( + AudacityProject *pProject, const wxString &fileName) { - auto newTrack = GetTrackFactory()->NewNoteTrack(); + AudacityProject *pNewProject {}; + if ( !pProject ) + pProject = pNewProject = CreateNewAudacityProject(); + auto cleanup = finally( [&] { if ( pNewProject ) pNewProject->Close(true); } ); + + auto newTrack = pProject->GetTrackFactory()->NewNoteTrack(); if (::ImportMIDI(fileName, newTrack.get())) { - SelectNone(); - auto pTrack = mTracks->Add(std::move(newTrack)); + pProject->SelectNone(); + auto pTrack = pProject->mTracks->Add(std::move(newTrack)); pTrack->SetSelected(true); - PushState(wxString::Format(_("Imported MIDI from '%s'"), + pProject->PushState(wxString::Format(_("Imported MIDI from '%s'"), fileName.c_str()), _("Import MIDI")); - RedrawProject(); - mTrackPanel->EnsureVisible(pTrack); + pProject->RedrawProject(); + pProject->mTrackPanel->EnsureVisible(pTrack); + pNewProject = nullptr; + return pProject; } + else + return nullptr; } #endif // USE_MIDI diff --git a/src/Menus.h b/src/Menus.h index f0c951d8d..19bb6ea9a 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -347,7 +347,12 @@ void OnRescanDevices(); void OnImport(); void OnImportLabels(); void OnImportMIDI(); -void DoImportMIDI(const wxString &fileName); + +// return null on failure; if success, return the given project, or a new +// one, if the given was null; create no new project if failure +static AudacityProject *DoImportMIDI( + AudacityProject *pProject, const wxString &fileName); + void OnImportRaw(); void OnEditMetadata(); diff --git a/src/Project.cpp b/src/Project.cpp index 137cd1be5..4c61ae08d 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -2891,14 +2891,13 @@ void AudacityProject::OpenFiles(AudacityProject *proj) // 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 || proj->mDirty || !proj->mTracks->IsEmpty()) { - // Open in a NEW window - proj = CreateNewAudacityProject(); - } + if ( proj && ( proj->mDirty || !proj->mTracks->IsEmpty() ) ) + 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->OpenFile(fileName); + proj = AudacityProject::OpenProject( proj, fileName ); } } @@ -2927,6 +2926,18 @@ bool AudacityProject::WarnOfLegacyFile( ) } +AudacityProject *AudacityProject::OpenProject( + AudacityProject *pProject, const wxString &fileNameArg, bool addtohistory) +{ + AudacityProject *pNewProject = nullptr; + if ( ! pProject ) + pProject = pNewProject = CreateNewAudacityProject(); + auto cleanup = finally( [&] { if( pNewProject ) pNewProject->Close(true); } ); + pProject->OpenFile( fileNameArg, addtohistory ); + pNewProject = nullptr; + return pProject; +} + // FIXME:? TRAP_ERR This should return a result that is checked. // See comment in AudacityApp::MRUOpen(). void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory) diff --git a/src/Project.h b/src/Project.h index 4198bef9f..971c92006 100644 --- a/src/Project.h +++ b/src/Project.h @@ -242,6 +242,14 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame, const wxString &extrafilter = wxEmptyString); static bool IsAlreadyOpen(const wxString & projPathName); static void OpenFiles(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. + static AudacityProject *OpenProject( + AudacityProject *pProject, + const wxString &fileNameArg, bool addtohistory = true); + void OpenFile(const wxString &fileName, bool addtohistory = true); private: diff --git a/src/import/ImportLOF.cpp b/src/import/ImportLOF.cpp index 730315639..7c87d112b 100644 --- a/src/import/ImportLOF.cpp +++ b/src/import/ImportLOF.cpp @@ -307,9 +307,12 @@ void LOFImportFileHandle::lofOpenFiles(wxString* ln) doDurationAndScrollOffset(); if (windowCalledOnce) - { - mProject = CreateNewAudacityProject(); - } + // Cause a project to be created with the next import + mProject = nullptr; + else + // Apply any offset and duration directives of the first "window" line + // to the previously open project, not a new one. + ; windowCalledOnce = true; @@ -388,7 +391,7 @@ void LOFImportFileHandle::lofOpenFiles(wxString* ln) if (targetfile.AfterLast(wxT('.')).IsSameAs(wxT("mid"), false) || targetfile.AfterLast(wxT('.')).IsSameAs(wxT("midi"), false)) { - mProject->DoImportMIDI(targetfile); + mProject = AudacityProject::DoImportMIDI(mProject, targetfile); } // If not a midi, open audio file @@ -399,9 +402,7 @@ void LOFImportFileHandle::lofOpenFiles(wxString* ln) * audio file. TODO: Some sort of message here? */ #endif // USE_MIDI - { - mProject->OpenFile(targetfile); - } + mProject = AudacityProject::OpenProject( mProject, targetfile ); // Set tok to right after filename temptok2.SetString(targettoken); @@ -427,7 +428,11 @@ void LOFImportFileHandle::lofOpenFiles(wxString* ln) double offset; // handle an "offset" specifier - if (Internat::CompatibleToDouble(tokenholder, &offset)) + if (!mProject) + // there was an import error, + // presumably with its own error message + ; + else if (Internat::CompatibleToDouble(tokenholder, &offset)) { Track *t; TrackListIterator iter(mProject->GetTracks()); @@ -489,6 +494,9 @@ void LOFImportFileHandle::lofOpenFiles(wxString* ln) void LOFImportFileHandle::doDurationAndScrollOffset() { + if (!mProject) + return; + bool doSomething = callDurationFactor || callScrollOffset; if (callDurationFactor) {