16#include <wx/evtloop.h>
77 auto result = std::make_shared< ProjectFileManager >( parent );
98 projectFileManager.ReadProjectFile(filename,
true);
100 if (projectFileManager.mLastSavedTracks) {
101 for (
auto wt : projectFileManager.mLastSavedTracks->Any<
WaveTrack>())
103 projectFileManager.mLastSavedTracks.reset();
120 "FAQ:Errors_on_opening_or_recovering_an_Audacity_project";
122using Pair = std::pair< const char *, const char * >;
125 "not well-formed (invalid token)",
126 "Error:_not_well-formed_(invalid_token)_at_line_x"
129 "reference to invalid character number",
130 "Error_Opening_Project:_Reference_to_invalid_character_number_at_line_x"
143 if ( !libraryError.
empty() ) {
146 auto msgid = libraryError.
MSGID().
GET();
148 [&](
const Pair &pair ) {
149 return msgid.Contains( pair.first ); }
152 auto url = found->second;
166 const FilePath &fileName,
bool discardAutosave )
176 auto parseResult = projectFileIO.LoadProject(fileName, discardAutosave);
177 const bool bParseSuccess = parseResult.has_value();
180 std::optional<TranslatableString> linkTypeChangeReason;
206 leader = left ?
nullptr
214 mLastSavedTracks->Add(newTrack);
223 [
this](
Track& track) {
224 mLastSavedTracks->Add(
231 [&](
const auto& errorMessage) { otherError = errorMessage; err =
true; },
232 [&](
const auto& unlinkReason) { linkTypeChangeReason = unlinkReason; });
235 if(linkTypeChangeReason && !discardAutosave)
243"This feature is not supported in Audacity versions past 3.3.3.\n"
244"These stereo tracks have been split into mono tracks.\n"
245"As a result, some realtime effects may be missing.\n"
246"Please verify that everything works as intended before saving."
247 ).
Format(linkTypeChangeReason->Translation()));
250 parseResult->Commit();
253 projectFileIO.AutoSaveDelete();
254 else if (projectFileIO.IsRecovered()) {
255 bool resaved =
false;
257 if (!projectFileIO.IsTemporary() &&
258 !linkTypeChangeReason)
262 resaved = projectFileIO.SaveProject(fileName,
nullptr);
268"This project was not saved properly the last time Audacity ran.\n\n"
269"It has been recovered to the last snapshot.")
271"This project was not saved properly the last time Audacity ran.\n\n"
272"It has been recovered to the last snapshot, but you must save it\n"
273"to preserve its contents."),
274 XO(
"Project Recovered"),
286 (bParseSuccess ? otherError : projectFileIO.GetLastError()),
296 mProject, [
this](
auto& path,
bool rename)
302 if (projectFileIO.IsTemporary())
307 return DoSave(projectFileIO.GetFileName(),
false);
327 ProjectDisabler(wxWindow *w)
330 mWindow->GetEventHandler()->SetEvtHandlerEnabled(
false);
334 mWindow->GetEventHandler()->SetEvtHandlerEnabled(
true);
358 wxULongLong fileSize = wxFileName::GetSize(projectFileIO.GetFileName());
360 wxDiskspaceSize_t freeSpace;
363 if (freeSpace.GetValue() <= fileSize.GetValue())
366 XO(
"Insufficient Disk Space"),
367 XO(
"The project size exceeds the available free space on the target disk.\n\n"
368 "Please select a different disk with more free space."),
369 "Error:_Disk_full_or_not_writable"
379 std::optional<ProjectFileIO::BackupProject> pBackupProject;
380 if (fromSaveAs && wxFileExists(fileName))
382 pBackupProject.emplace(projectFileIO, fileName);
383 if (!pBackupProject->IsOk())
389 if (wxFileName::GetSize(projectFileIO.GetFileName()) > UINT32_MAX)
392 XO(
"Error Saving Project"),
393 XO(
"The project exceeds the maximum size of 4GB when writing to a FAT32 formatted filesystem."),
394 "Error:_Unsuitable_drive"
405 if (!projectFileIO.HasConnection()) {
408 XO(
"Error Saving Project"),
410 "Error:_Disk_full_or_not_writable",
416 proj.SetProjectName(wxFileName(fileName).GetName());
417 projectFileIO.SetProjectTitle();
435 pBackupProject->Discard();
447 auto oldFileName = projectFileIO.GetFileName();
449 bool bOwnsNewName = !projectFileIO.IsTemporary() && (oldFileName == newFileName);
453 if( !bOwnsNewName && wxFileExists(newFileName)) {
456 XO(
"The project was not saved because the file name provided would overwrite another project.\nPlease try again and select an original name."),
457 XO(
"Error Saving Project"),
463 auto success =
DoSave(newFileName, !bOwnsNewName);
464 if (success && addToHistory) {
480 if (projectFileIO.IsTemporary()) {
481 filename.SetPath(defaultSavePath);
482 filename.SetName(
project.GetProjectName());
485 filename = projectFileIO.GetFileName();
490 filename.SetPath(defaultSavePath);
496 bool bPrompt = (
project.mBatchMode == 0) || (projectFileIO.GetFileName().empty());
504 fName =
SelectFile(FileNames::Operation::Save,
507 filename.GetFullName(),
510 wxFD_SAVE | wxRESIZE_BORDER,
519 filename.SetExt(
wxT(
"aup3"));
521 if ((!bPrompt || !allowOverwrite) && filename.FileExists()) {
525 XO(
"The project was not saved because the file name provided would overwrite another project.\nPlease try again and select an original name."),
526 XO(
"Error Saving Project"),
532 fName = filename.GetFullPath();
534 bOwnsNewName = !projectFileIO.IsTemporary() && ( projectFileIO.GetFileName() == fName );
538 if (!bOwnsNewName && filename.FileExists()) {
545 int mayOverwrite = ( projectFileIO.GetFileName() == fName ) ? 2 : 1;
548 if (openProjectName.SameAs(fName)) {
550 if (mayOverwrite == 0)
555 if (mayOverwrite > 0) {
559 Do you want to overwrite the project:\n\"%s\"?\n\n\
560 If you select \"Yes\" the project\n\"%s\"\n\
561 will be irreversibly overwritten.").Format( fName, fName );
567 XO(
"Overwrite Project Warning"),
568 wxYES_NO | wxNO_DEFAULT | wxICON_WARNING,
570 if (result == wxNO) {
573 if (result == wxCANCEL) {
581 XO(
"The project was not saved because the selected project is open in another window.\nPlease try again and select an original name."),
582 XO(
"Error Saving Project"),
602 auto success =
DoSave(fName, !bOwnsNewName);
616 wxFileName filename = fileName;
619 if (fileName.empty())
621 if (projectFileIO.IsTemporary())
623 filename.SetPath(defaultSavePath);
627 filename = projectFileIO.GetFileName();
634 filename.SetPath(defaultSavePath);
638 XO(
"%sSave Copy of Project \"%s\" As...")
641 bool bPrompt = (
project.mBatchMode == 0) || (projectFileIO.GetFileName().empty());
653 fName =
SelectFile(FileNames::Operation::Export,
656 filename.GetFullName(),
659 wxFD_SAVE | wxRESIZE_BORDER,
670 filename.SetExt(
wxT(
"aup3"));
682 if (filename.FileExists())
686 XO(
"Saving a copy must not overwrite an existing saved project.\nPlease try again and select an original name."),
687 XO(
"Error Saving Copy of Project"),
688 wxOK | wxICON_ERROR);
699 wxULongLong fileSize = wxFileName::GetSize(projectFileIO.GetFileName());
701 wxDiskspaceSize_t freeSpace;
704 if (freeSpace.GetValue() <= fileSize.GetValue())
707 XO(
"Insufficient Disk Space"),
708 XO(
"The project size exceeds the available free space on the target disk.\n\n"
709 "Please select a different disk with more free space."),
710 "Error:_Unsuitable_drive"
719 if (fileSize > UINT32_MAX)
722 XO(
"Error Saving Project"),
723 XO(
"The project exceeds the maximum size of 4GB when writing to a FAT32 formatted filesystem."),
724 "Error:_Unsuitable_drive"
736 fName = filename.GetFullPath();
740 if (!projectFileIO.SaveCopy(fName))
744 nullptr, msg,
XO(
"Error Saving Project"), wxOK | wxICON_ERROR);
762 wxString sNewFileName = fnFile.GetFullPath();
767 if (!projectFileIO.IsModified()) {
768 sOldFilename = projectFileIO.GetFileName();
774 if (wxFileExists(sNewFileName)) {
778 auto success =
DoSave(sNewFileName,
true);
810 return projectFileIO.OpenProject();
834 projectFileIO.CloseProject();
856 wxArrayString selected;
859 XO(
"Select one or more files"),
863 wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER);
871 const auto &saveType = fileTypes[ index ];
876 if (dialogResult == wxID_OK) {
890 const wxFileName newProjPathName(projPathName);
892 iter = std::find_if( start, finish,
896 if (iter != finish) {
898 XO(
"%s is already open in another window.")
899 .Format( newProjPathName.GetName() );
900 wxLogError(errMsg.Translation());
903 XO(
"Error Opening Project"),
911 const FilePath &fileNameArg,
bool addtohistory)
931 if (fileName.Lower().EndsWith(
wxT(
".aup3.bak")))
935"You are trying to open an automatically created backup file.\nDoing this may result in severe data loss.\n\nPlease open the actual Audacity project file instead."),
936 XO(
"Warning - Backup File Detected"),
942 if (!::wxFileExists(fileName)) {
944 XO(
"Could not open file: %s").
Format( fileName ),
945 XO(
"Error Opening File"),
953 wxFFile ff(fileName,
wxT(
"rb"));
955 auto cleanup =
finally([&]
963 if (!ff.IsOpened()) {
965 XO(
"Could not open file: %s").
Format( fileName ),
966 XO(
"Error opening file"),
973 auto numRead = ff.Read(buf, 6);
976 XO(
"File may be invalid or corrupted: \n%s").
Format( fileName ),
977 XO(
"Error Opening File or Project"),
983 if (wxStrncmp(buf,
"SQLite", 6) != 0)
986#ifdef EXPERIMENTAL_DRAG_DROP_PLUG_INS
995 auto &
project = chooser(
false);
1001 if (!fileName.AfterLast(
'.').IsSameAs(
wxT(
"lof"),
false))
1012 XO(
"Project resides on FAT formatted drive.\n"
1013 "Copy it to another drive to open it.")))
1018 auto &
project = chooser(
true);
1031 for (
auto iter =
tracks.begin(); iter !=
tracks.end();) {
1032 auto t = (*iter++)->SharedPointer();
1033 const auto linkType = t->GetLinkType();
1037 if (!t->LinkConsistencyFix()) {
1038 onError(
XO(
"A channel of a stereo track was missing."));
1039 unlinkedTrack =
nullptr;
1041 if (!unlinkedTrack) {
1043 t->NChannels() == 1) {
1046 assert(t->GetOwner().get() == &
tracks);
1051 iter =
tracks.Find(t.get());
1058 if (
const auto left =
dynamic_cast<WaveTrack*
>(unlinkedTrack.get())) {
1059 if (
const auto right =
dynamic_cast<WaveTrack*
>(t.get())) {
1061 assert(right->GetOwner().get() == &
tracks);
1062 left->SetPan(-1.0f);
1063 right->SetPan(1.0f);
1067 if(left->GetRate() != right->GetRate())
1069 onUnlink(
XO(
"This project contained stereo tracks with different sample rates per channel."));
1070 if(left->GetSampleFormat() != right->GetSampleFormat())
1072 onUnlink(
XO(
"This project contained stereo tracks with different sample formats in channels."));
1074 onUnlink(
XO(
"This project contained stereo tracks with non-aligned content."));
1077 unlinkedTrack =
nullptr;
1080 if (
const auto message = t->GetErrorOpening()) {
1082 wxT(
"Track %s had error reading clip values from project file."),
1090 const FilePath &fileName,
bool addtohistory)
1105 const bool bParseSuccess = results.parseSuccess;
1106 const auto &errorStr = results.errorString;
1107 const bool err = results.trackError;
1109 if (bParseSuccess && !err) {
1114 viewport.HandleResize();
1115 trackPanel.Refresh(
false);
1119 trackPanel.Update();
1127 if (bParseSuccess && !err) {
1128 if (projectFileIO.IsRecovered())
1131 history.PushState(
XO(
"Project was recovered"),
XO(
"Recover"));
1151 wxLogError(
wxT(
"Could not parse file \"%s\". \nError: %s"), fileName, errorStr.Debug());
1154 XO(
"Error Opening Project"),
1171 std::vector<Track*> results;
1175 wxFileName
fn(fileName);
1177 bool initiallyEmpty =
tracks.empty();
1179 wxString trackNameBase =
fn.GetName();
1185 const bool projectHasSolo =
1187 if (projectHasSolo) {
1188 for (
auto &group : newTracks)
1189 if (
auto pTrack =
dynamic_cast<PlayableTrack*
>(group.get()))
1190 pTrack->SetMute(
true);
1193 for (
auto &group : newTracks) {
1194 if (
auto pTrack =
dynamic_cast<WaveTrack*
>(group.get()))
1195 results.push_back(pTrack);
1204 const bool useSuffix = results.size() > 1;
1206 for (
const auto &newTrack : results) {
1208 newTrack->SetSelected(
true);
1211 newTrack->SetName(
XC(
"%s %d",
"clip name template")
1212 .Format(trackNameBase, i + 1).Translation());
1214 newTrack->SetName(trackNameBase);
1216 newTrack->TypeSwitch([&](
WaveTrack &wt) {
1219 const auto trackName = wt.
GetName();
1220 for (
const auto &interval : wt.
Intervals())
1221 interval->SetName(trackName);
1225 history.PushState(
XO(
"Imported '%s'").Format( fileName ),
1228#if defined(__WXGTK__)
1234 wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI | wxEVT_CATEGORY_USER_INPUT);
1239 if (initiallyEmpty && projectFileIO.IsTemporary()) {
1241 project.SetInitialImportPath(
fn.GetPath());
1242 projectFileIO.SetProjectTitle();
1256 if (!projectFileIO.LoadProject(fileName,
false))
1260 for (
const Track *pTrack : srcTracks)
1261 pTrack->PasteInto(dest, destTracks);
1281 mImportFileHandle = &importFileHandle;
1287 if (ImportDlg.ShowModal() == wxID_CANCEL)
1298 constexpr double ProgressSteps { 1000.0 };
1299 if(!mProgressDialog)
1301 wxFileName ff( mImportFileHandle->GetFilename() );
1302 auto title =
XO(
"Importing %s").Format( mImportFileHandle->GetFileDescription() );
1305 auto result = mProgressDialog->Poll(progress * ProgressSteps, ProgressSteps);
1307 mImportFileHandle->Cancel();
1309 mImportFileHandle->Stop();
1314 mProgressDialog.reset();
1315 if(result == ImportResult::Error)
1317 auto message = mImportFileHandle->GetErrorMessage();
1318 if(!message.empty())
1335 wxArrayString fileNames;
1336 fileNames.Add(fileName);
1337 return Import(std::move(fileNames), addToHistory);
1344 std::vector<wxString> { fileNames.begin(), fileNames.end() },
1349 Track* lastTrack =
nullptr;
1351 assert(!range.empty());
1354 lastTrack = *(range.rbegin());
1356 const auto project = wProject.lock();
1357 const auto track = wTrack.lock();
1358 if (!project || !track)
1360 auto& viewPort = Viewport::Get(*project);
1361 TrackFocus::Get(*project).Set(track.get(), true);
1362 viewPort.ZoomFitHorizontally();
1363 viewPort.ShowTrack(*track);
1364 viewPort.HandleResize();
1372 const std::vector<std::shared_ptr<ClipMirAudioReader>>& readers,
1375 const auto isBeatsAndMeasures =
project.ViewIsBeatsAndMeasures();
1376 const auto projectTempo =
project.GetTempo();
1380 XO(
"Music Information Retrieval"),
XO(
"Analyzing imported audio"),
1383 const auto reportProgress = [&](
double progressFraction) {
1384 const auto result = progress->Poll(
1385 (count + progressFraction) / readers.size() * 1000, 1000);
1390 std::vector<std::shared_ptr<MIR::AnalyzedAudioClip>> analyzedClips;
1391 analyzedClips.reserve(readers.size());
1393 readers.begin(), readers.end(), std::back_inserter(analyzedClips),
1394 [&](
const std::shared_ptr<ClipMirAudioReader>& reader) {
1395 const MIR::ProjectSyncInfoInput input {
1396 *reader, reader->filename, reader->tags, reportProgress,
1397 projectTempo, projectWasEmpty, isBeatsAndMeasures,
1401 return std::make_shared<AnalyzedWaveClip>(reader, syncInfo);
1403 return analyzedClips;
1408 const std::vector<FilePath>& fileNames,
bool addToHistory)
1410 const auto projectWasEmpty =
1412 std::vector<std::shared_ptr<ClipMirAudioReader>> resultingReaders;
1413 const auto success = std::all_of(
1414 fileNames.begin(), fileNames.end(), [&](
const FilePath& fileName) {
1415 std::shared_ptr<ClipMirAudioReader> resultingReader;
1416 const auto success = DoImport(fileName, addToHistory, resultingReader);
1417 if (success && resultingReader)
1418 resultingReaders.push_back(std::move(resultingReader));
1424 if (!resultingReaders.empty())
1426 const auto pProj =
mProject.shared_from_this();
1429 const auto analyzedClips =
1439 const FilePath& fileName,
bool addToHistory,
1440 std::shared_ptr<ClipMirAudioReader>& resultingReader)
1449#ifdef EXPERIMENTAL_IMPORT_AUP3
1451 if (fileName.AfterLast(
'.').IsSameAs(
wxT(
"aup3"),
false)) {
1457 if (initiallyEmpty && projectFileIO.IsTemporary()) {
1458 wxFileName
fn(fileName);
1460 project.SetInitialImportPath(
fn.GetPath());
1461 projectFileIO.SetProjectTitle();
1464 history.PushState(
XO(
"Imported '%s'").
Format(fileName),
XO(
"Import"));
1471 errorMessage = projectFileIO.GetLastError();
1472 if (errorMessage.
empty()) {
1473 errorMessage =
XO(
"Failed to import project");
1478 XO(
"Error Importing"),
1479 errorMessage,
wxT(
"Importing_Audio"));
1488 bool committed =
false;
1489 auto cleanup =
finally([&]{
1493 auto newTags = oldTags->Duplicate();
1496#ifndef EXPERIMENTAL_IMPORT_AUP3
1498 if (fileName.AfterLast(
'.').IsSameAs(
wxT(
"aup3"),
false)) {
1500 XO(
"Error Importing"),
1501 XO(
"Cannot import AUP3 format. Use File > Open instead"),
1507 ImportProgress importProgress(
project);
1508 std::optional<LibFileFormats::AcidizerTags> acidTags;
1511 newTracks, newTags.get(), acidTags, errorMessage);
1512 if (!errorMessage.
empty()) {
1516 XO(
"Error Importing"), errorMessage,
wxT(
"Importing_Audio"));
1522 for (
auto track : newTracks)
1525 if (newTracks.size() == 1)
1527 const auto waveTrack =
dynamic_cast<WaveTrack*
>(newTracks[0].get());
1530 if (waveTrack && !waveTrack->GetClipInterfaces().empty())
1532 std::move(acidTags), fileName.ToStdString(),
1546 if (fileName.AfterLast(
'.').IsSameAs(
wxT(
"lof"),
false)) {
1556 if (fileName.AfterLast(
'.').IsSameAs(
wxT(
"aup"),
false)) {
1559 if (initiallyEmpty && projectFileIO.IsTemporary()) {
1560 wxFileName
fn(fileName);
1562 project.SetInitialImportPath(
fn.GetPath());
1563 projectFileIO.SetProjectTitle();
1568 history.PushState(
XO(
"Imported '%s'").
Format( fileName ),
XO(
"Import"));
1574 AddImportedTracks(fileName, std::move(newTracks));
1593 S.StartVerticalLay(
true);
1595 S.AddFixedText(text,
false, 500);
1601 FindWindowById(wxID_YES,
this)->Bind(wxEVT_BUTTON, &CompactDialog::OnYes,
this);
1602 FindWindowById(wxID_NO,
this)->Bind(wxEVT_BUTTON, &CompactDialog::OnNo,
this);
1603 FindWindowById(wxID_HELP,
this)->Bind(wxEVT_BUTTON, &CompactDialog::OnGetURL,
this);
1610 void OnYes(wxCommandEvent &WXUNUSED(evt))
1615 void OnNo(wxCommandEvent &WXUNUSED(evt))
1633 bool isBatch =
project.mBatchMode > 0;
1636 projectFileIO.ReopenProject();
1638 auto savedState = undoManager.GetSavedState();
1639 const auto currentState = undoManager.GetCurrentState();
1640 if (savedState < 0) {
1641 undoManager.StateSaved();
1642 savedState = undoManager.GetSavedState();
1643 if (savedState < 0) {
1648 const auto least = std::min<size_t>(savedState, currentState);
1649 const auto greatest = std::max<size_t>(savedState, currentState);
1650 std::vector<const TrackList*> trackLists;
1653 trackLists.push_back(pTracks);
1655 undoManager.VisitStates(
fn, least, 1 + least);
1656 if (least != greatest)
1657 undoManager.VisitStates(
fn, greatest, 1 + greatest);
1659 int64_t total = projectFileIO.GetTotalUsage();
1660 int64_t used = projectFileIO.GetCurrentUsage(trackLists);
1662 auto before = wxFileName::GetSize(projectFileIO.GetFileName());
1665 XO(
"Compacting this project will free up disk space by removing unused bytes within the file.\n\n"
1666 "There is %s of free disk space and this project is currently using %s.\n"
1668 "If you proceed, the current Undo/Redo History and clipboard contents will be discarded "
1669 "and you will recover approximately %s of disk space.\n"
1671 "Do you want to continue?")
1675 if (isBatch || dlg.ShowModal() == wxYES)
1678 undoManager.RemoveStates(1 + greatest, undoManager.GetNumStates());
1681 if (least < greatest)
1682 undoManager.RemoveStates(least + 1, greatest);
1685 undoManager.RemoveStates(0, least);
1688 if (&
mProject == clipboard.Project().lock().get())
1693 auto before = wxFileName::GetSize(projectFileIO.GetFileName());
1695 projectFileIO.Compact(trackLists,
true);
1697 auto after = wxFileName::GetSize(projectFileIO.GetFileName());
1702 XO(
"Compacting actually freed %s of disk space.")
1704 XO(
"Compact Project"));
1707 undoManager.RenameState( undoManager.GetCurrentState(),
1708 XO(
"Compacted project file"),
1718 bShowProjectNumbers ? pProject->GetProjectNumber() : -1 );
1726 if( window.IsIconized() )
1737 return ptr->GetProjectName().empty();
1742 _(
"[Project %02i] "),
project.GetProjectNumber() + 1 );
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Toolkit-neutral facade for basic user interface services.
Declare functions to perform UTF-8 to std::wstring conversions.
The interface that all file import "plugins" (if you want to call them that) must implement....
std::vector< std::shared_ptr< Track > > TrackHolders
std::unique_ptr< const BasicUI::WindowPlacement > ProjectFramePlacement(AudacityProject *project)
Make a WindowPlacement object suitable for project (which may be null)
@ Cancel
Open was cancelled by the extension.
@ Handled
Save was handled by the extension.
@ Continue
Save was not handled by the extension.
@ Veto
Extension vetoed the close.
static const AudacityProject::AttachedObjects::RegisteredFactory sFileManagerKey
static void RefreshAllTitles(bool bShowProjectNumbers)
an object holding per-project preferred sample rate
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
accessors for certain important windows associated with each project
FilePath SelectFile(FileNames::Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
void DoProjectTempoChange(ChannelGroup &group, double newTempo)
static Settings & settings()
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
An AudacityException with no visible message.
const_iterator end() const
Container::value_type value_type
const_iterator begin() const
Wrap wxMessageDialog so that caption IS translatable.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
virtual int GetFilterIndex() const
virtual wxString GetPath() const
virtual void GetPaths(wxArrayString &paths) const
virtual void SetFilterIndex(int filterIndex)
static TranslatableString WriteFailureMessage(const wxFileName &fileName)
void Append(const FilePath &file)
static FileHistory & Global()
FILES_API const FileType AudacityProjects
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
const wxString & GET() const
Explicit conversion to wxString, meant to be ugly-looking and demanding of a comment why it's correct...
Base class for FlacImportFileHandle, LOFImportFileHandle, MP3ImportFileHandle, OggImportFileHandle an...
virtual wxInt32 GetStreamCount()=0
virtual void SetStreamUsage(wxInt32 StreamID, bool Use)=0
Interface used to report on import state and progress.
static void SetLastOpenType(const FileNames::FileType &type)
FileNames::FileTypes GetFileTypes(const FileNames::FileType &extraType={})
bool Import(AudacityProject &project, const FilePath &fName, ImportProgressListener *importProgressListener, WaveTrackFactory *trackFactory, TrackHolders &tracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &outAcidTags, TranslatableString &errorMessage)
static size_t SelectDefaultOpenType(const FileNames::FileTypes &fileTypes)
static void SetDefaultOpenType(const FileNames::FileType &type)
static TranslatableString FormatSize(wxLongLong size)
Convert a number to a string while formatting it in bytes, KB, MB, GB.
Makes a temporary project that doesn't display on the screen.
AudacityProject & Project()
AudioTrack subclass that can also be audibly replayed by the program.
static PluginManager & Get()
void SetProjectTitle(int number=-1)
static ProjectFileIO & Get(AudacityProject &project)
const FilePath & GetFileName() const
static void FixTracks(TrackList &tracks, const std::function< void(const TranslatableString &)> &onError, const std::function< void(const TranslatableString &)> &onUnlink)
Attempts to find and fix problems in tracks.
std::shared_ptr< TrackList > mLastSavedTracks
static bool IsAlreadyOpen(const FilePath &projPathName)
AudacityProject & mProject
void CompactProjectOnClose()
bool Import(const FilePath &fileName, bool addToHistory=true)
bool ImportAndRunTempoDetection(const std::vector< FilePath > &fileNames, bool addToHistory)
bool SaveCopy(const FilePath &fileName=wxT(""))
bool SaveAs(bool allowOverwrite=false)
static void DiscardAutosave(const FilePath &filename)
void AddImportedTracks(const FilePath &fileName, TrackHolders &&newTracks)
static wxArrayString ShowOpenDialog(FileNames::Operation op, const FileNames::FileType &extraType={})
Show an open dialogue for opening audio files, and possibly other sorts of files.
bool DoSave(const FilePath &fileName, bool fromSaveAs)
bool SaveFromTimerRecording(wxFileName fnFile)
static AudacityProject * OpenFile(const ProjectChooserFn &chooser, const FilePath &fileName, bool addtohistory=true)
ReadProjectResults ReadProjectFile(const FilePath &fileName, bool discardAutosave=false)
bool DoImport(const FilePath &fileName, bool addToHistory, std::shared_ptr< ClipMirAudioReader > &resultingReader)
std::function< AudacityProject &(bool)> ProjectChooserFn
A function that returns a project to use for opening a file; argument is true if opening a project fi...
static ProjectFileManager & Get(AudacityProject &project)
ProjectFileManager(AudacityProject &project)
AudacityProject * OpenProjectFile(const FilePath &fileName, bool addtohistory)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
static ProjectStatus & Get(AudacityProject &project)
void Set(const TranslatableString &msg, StatusBarField field=MainStatusBarField())
static ProjectTimeSignature & Get(AudacityProject &project)
static RealtimeEffectList & Get(AudacityProject &project)
void Clear()
Use only in the main thread. Sends Remove messages.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
TitleRestorer(wxTopLevelWindow &window, AudacityProject &project)
Abstract base class for an object holding data associated with points on a time axis.
std::shared_ptr< Track > Holder
const wxString & GetName() const
Name is always the same for all channels of a group.
virtual Holder Duplicate(DuplicateOptions={}) const
public nonvirtual duplication function that invokes Clone()
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
static TrackListHolder Create(AudacityProject *pOwner)
auto Any() -> TrackIterRange< TrackType >
static TrackList & Get(AudacityProject &project)
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
static TrackPanel & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
Identifier MSGID() const
MSGID is the English lookup key in the catalog, not necessarily for user's eyes if locale is some oth...
static UndoManager & Get(AudacityProject &project)
An error dialog about unwritable location, that allows to navigate to settings quickly.
Can be thrown when user cancels operations, as with a progress dialog. Delayed handler does nothing.
void ZoomFitHorizontallyAndShowTrack(Track *pTrack)
static Viewport & Get(AudacityProject &project)
static WaveTrackFactory & Get(AudacityProject &project)
A Track that contains audio waveform data.
void ZipClips(bool mustAlign=true)
double GetRate() const override
void OnYes(wxCommandEvent &WXUNUSED(evt))
void OnGetURL(wxCommandEvent &WXUNUSED(evt))
CompactDialog(TranslatableString text)
void OnNo(wxCommandEvent &WXUNUSED(evt))
void OnImportResult(ImportResult result) override
Used to report on import result for file handle passed as argument to OnImportFileOpened.
ImportProgress(AudacityProject &project)
void OnImportProgress(double progress) override
bool OnImportFileOpened(ImportFileHandle &importFileHandle) override
wxWeakRef< AudacityProject > mProject
std::unique_ptr< BasicUI::ProgressDialog > mProgressDialog
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
void ShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options={})
Show an error dialog with a link to the manual for further help.
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
std::unique_ptr< ProgressDialog > MakeProgress(const TranslatableString &title, const TranslatableString &message, unsigned flags=(ProgressShowStop|ProgressShowCancel), const TranslatableString &remainingLabelText={})
Create and display a progress dialog.
FILES_API bool IsOnFATFileSystem(const FilePath &path)
FILES_API bool IsPathAvailable(const FilePath &Path)
FILES_API wxString AbbreviatePath(const wxFileName &fileName)
Give enough of the path to identify the device. (On Windows, drive letter plus ':')
FILES_API void UpdateDefaultPath(Operation op, const FilePath &path)
FILES_API int CompareNoCase(const wxString &first, const wxString &second)
FILES_API FilePath FindDefaultPath(Operation op)
std::optional< ProjectSyncInfo > GetProjectSyncInfo(const ProjectSyncInfoInput &in)
void SynchronizeProject(const std::vector< std::shared_ptr< AnalyzedAudioClip > > &clips, ProjectInterface &project, bool projectWasEmpty)
void SelectNone(AudacityProject &project)
FILES_API bool FATFilesystemDenied(const FilePath &path, const TranslatableString &msg, const BasicUI::WindowPlacement &placement={})
FILES_API wxString UnsavedProjectFileName()
TRACK_API TrackList * Find(const UndoStackElem &state)
WAVE_TRACK_API void CloseLock(WaveTrack &track) noexcept
Should be called upon project close. Not balanced by unlocking calls.
bool ImportProject(AudacityProject &dest, const FilePath &fileName)
std::pair< const char *, const char * > Pair
const Pair helpURLTable[]
wxString FindHelpUrl(const TranslatableString &libraryError)
const char *const defaultHelpUrl
std::vector< std::shared_ptr< MIR::AnalyzedAudioClip > > RunTempoDetection(const std::vector< std::shared_ptr< ClipMirAudioReader > > &readers, const MIR::ProjectInterface &project, bool projectWasEmpty)
TranslatableString Message(unsigned trackCount)
std::string ToUTF8(const std::wstring &wstr)
wxString ToWXString(const std::string &str)
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept
Options for variations of error dialogs; the default is for modal dialogs.
static void OnLoad(AudacityProject &project)
static OnOpenAction OnOpen(AudacityProject &project, const std::string &path)
static OnSaveAction OnSave(AudacityProject &project, const ProjectSaveCallback &projectSaveCallback)
static OnCloseAction OnClose(AudacityProject &project)
Choices when duplicating a track.
DuplicateOptions Backup() &&
Holds one item with description and time range for the UndoManager.