16#include <wx/evtloop.h>
76 auto result = std::make_shared< ProjectFileManager >( parent );
97 projectFileManager.ReadProjectFile(filename,
true);
99 if (projectFileManager.mLastSavedTracks) {
100 for (
auto wt : projectFileManager.mLastSavedTracks->Any<
WaveTrack>())
102 projectFileManager.mLastSavedTracks.reset();
119 "FAQ:Errors_on_opening_or_recovering_an_Audacity_project";
121using Pair = std::pair< const char *, const char * >;
124 "not well-formed (invalid token)",
125 "Error:_not_well-formed_(invalid_token)_at_line_x"
128 "reference to invalid character number",
129 "Error_Opening_Project:_Reference_to_invalid_character_number_at_line_x"
142 if ( !libraryError.
empty() ) {
145 auto msgid = libraryError.
MSGID().
GET();
147 [&](
const Pair &pair ) {
148 return msgid.Contains( pair.first ); }
151 auto url = found->second;
165 const FilePath &fileName,
bool discardAutosave )
175 auto parseResult = projectFileIO.LoadProject(fileName, discardAutosave);
176 const bool bParseSuccess = parseResult.has_value();
179 std::optional<TranslatableString> linkTypeChangeReason;
207 :
static_cast<WaveTrack*
>(newTrack.get())
210 mLastSavedTracks->Add(newTrack);
223 [&](
const auto& errorMessage) { otherError = errorMessage; err =
true; },
224 [&](
const auto& unlinkReason) { linkTypeChangeReason = unlinkReason; });
227 if(linkTypeChangeReason && !discardAutosave)
235"This feature is not supported in Audacity versions past 3.3.3.\n"
236"These stereo tracks have been split into mono tracks.\n"
237"As a result, some realtime effects may be missing.\n"
238"Please verify that everything works as intended before saving."
239 ).
Format(linkTypeChangeReason->Translation()));
242 parseResult->Commit();
245 projectFileIO.AutoSaveDelete();
246 else if (projectFileIO.IsRecovered()) {
247 bool resaved =
false;
249 if (!projectFileIO.IsTemporary() &&
250 !linkTypeChangeReason)
254 resaved = projectFileIO.SaveProject(fileName,
nullptr);
260"This project was not saved properly the last time Audacity ran.\n\n"
261"It has been recovered to the last snapshot.")
263"This project was not saved properly the last time Audacity ran.\n\n"
264"It has been recovered to the last snapshot, but you must save it\n"
265"to preserve its contents."),
266 XO(
"Project Recovered"),
278 (bParseSuccess ? otherError : projectFileIO.GetLastError()),
289 mProject, [
this](
auto& path,
bool rename)
295 if (projectFileIO.IsTemporary())
300 return DoSave(projectFileIO.GetFileName(),
false);
320 ProjectDisabler(wxWindow *w)
323 mWindow->GetEventHandler()->SetEvtHandlerEnabled(
false);
327 mWindow->GetEventHandler()->SetEvtHandlerEnabled(
true);
359 "Your project is now empty.\nIf saved, the project will have no tracks.\n\nTo save any previously open tracks:\nClick 'No', Edit > Undo until all tracks\nare open, then File > Save Project.\n\nSave anyway?"),
360 XO(
"Warning - Empty Project"),
361 wxYES_NO | wxICON_QUESTION,
370 wxULongLong fileSize = wxFileName::GetSize(projectFileIO.GetFileName());
372 wxDiskspaceSize_t freeSpace;
375 if (freeSpace.GetValue() <= fileSize.GetValue())
378 XO(
"Insufficient Disk Space"),
379 XO(
"The project size exceeds the available free space on the target disk.\n\n"
380 "Please select a different disk with more free space."),
381 "Error:_Disk_full_or_not_writable"
391 std::optional<ProjectFileIO::BackupProject> pBackupProject;
392 if (fromSaveAs && wxFileExists(fileName))
394 pBackupProject.emplace(projectFileIO, fileName);
395 if (!pBackupProject->IsOk())
401 if (wxFileName::GetSize(projectFileIO.GetFileName()) > UINT32_MAX)
404 XO(
"Error Saving Project"),
405 XO(
"The project exceeds the maximum size of 4GB when writing to a FAT32 formatted filesystem."),
406 "Error:_Unsuitable_drive"
417 if (!projectFileIO.HasConnection()) {
420 XO(
"Error Saving Project"),
422 "Error:_Disk_full_or_not_writable",
428 proj.SetProjectName(wxFileName(fileName).GetName());
429 projectFileIO.SetProjectTitle();
447 pBackupProject->Discard();
459 auto oldFileName = projectFileIO.GetFileName();
461 bool bOwnsNewName = !projectFileIO.IsTemporary() && (oldFileName == newFileName);
465 if( !bOwnsNewName && wxFileExists(newFileName)) {
468 XO(
"The project was not saved because the file name provided would overwrite another project.\nPlease try again and select an original name."),
469 XO(
"Error Saving Project"),
475 auto success =
DoSave(newFileName, !bOwnsNewName);
476 if (success && addToHistory) {
492 if (projectFileIO.IsTemporary()) {
493 filename.SetPath(defaultSavePath);
494 filename.SetName(
project.GetProjectName());
497 filename = projectFileIO.GetFileName();
502 filename.SetPath(defaultSavePath);
508'Save Project' is for an Audacity project, not an audio file.\n\
509For an audio file that will open in other apps, use 'Export'.\n");
515 bool bPrompt = (
project.mBatchMode == 0) || (projectFileIO.GetFileName().empty());
523 fName =
SelectFile(FileNames::Operation::Save,
526 filename.GetFullName(),
529 wxFD_SAVE | wxRESIZE_BORDER,
538 filename.SetExt(
wxT(
"aup3"));
540 if ((!bPrompt || !allowOverwrite) && filename.FileExists()) {
544 XO(
"The project was not saved because the file name provided would overwrite another project.\nPlease try again and select an original name."),
545 XO(
"Error Saving Project"),
551 fName = filename.GetFullPath();
553 bOwnsNewName = !projectFileIO.IsTemporary() && ( projectFileIO.GetFileName() == fName );
557 if (!bOwnsNewName && filename.FileExists()) {
564 int mayOverwrite = ( projectFileIO.GetFileName() == fName ) ? 2 : 1;
567 if (openProjectName.SameAs(fName)) {
569 if (mayOverwrite == 0)
574 if (mayOverwrite > 0) {
578 Do you want to overwrite the project:\n\"%s\"?\n\n\
579 If you select \"Yes\" the project\n\"%s\"\n\
580 will be irreversibly overwritten.").Format( fName, fName );
586 XO(
"Overwrite Project Warning"),
587 wxYES_NO | wxNO_DEFAULT | wxICON_WARNING,
589 if (result == wxNO) {
592 if (result == wxCANCEL) {
600 XO(
"The project was not saved because the selected project is open in another window.\nPlease try again and select an original name."),
601 XO(
"Error Saving Project"),
621 auto success =
DoSave(fName, !bOwnsNewName);
635 wxFileName filename = fileName;
638 if (fileName.empty())
640 if (projectFileIO.IsTemporary())
642 filename.SetPath(defaultSavePath);
646 filename = projectFileIO.GetFileName();
653 filename.SetPath(defaultSavePath);
657 XO(
"%sSave Copy of Project \"%s\" As...")
660 bool bPrompt = (
project.mBatchMode == 0) || (projectFileIO.GetFileName().empty());
672 fName =
SelectFile(FileNames::Operation::Export,
675 filename.GetFullName(),
678 wxFD_SAVE | wxRESIZE_BORDER,
689 filename.SetExt(
wxT(
"aup3"));
701 if (filename.FileExists())
705 XO(
"Saving a copy must not overwrite an existing saved project.\nPlease try again and select an original name."),
706 XO(
"Error Saving Copy of Project"),
707 wxOK | wxICON_ERROR);
718 wxULongLong fileSize = wxFileName::GetSize(projectFileIO.GetFileName());
720 wxDiskspaceSize_t freeSpace;
723 if (freeSpace.GetValue() <= fileSize.GetValue())
726 XO(
"Insufficient Disk Space"),
727 XO(
"The project size exceeds the available free space on the target disk.\n\n"
728 "Please select a different disk with more free space."),
729 "Error:_Unsuitable_drive"
738 if (fileSize > UINT32_MAX)
741 XO(
"Error Saving Project"),
742 XO(
"The project exceeds the maximum size of 4GB when writing to a FAT32 formatted filesystem."),
743 "Error:_Unsuitable_drive"
755 fName = filename.GetFullPath();
759 if (!projectFileIO.SaveCopy(fName))
763 nullptr, msg,
XO(
"Error Saving Project"), wxOK | wxICON_ERROR);
781 wxString sNewFileName = fnFile.GetFullPath();
786 if (!projectFileIO.IsModified()) {
787 sOldFilename = projectFileIO.GetFileName();
793 if (wxFileExists(sNewFileName)) {
797 auto success =
DoSave(sNewFileName,
true);
822 if ( !projectFileIO.WasCompacted() &&
840 return projectFileIO.OpenProject();
864 projectFileIO.CloseProject();
886 wxArrayString selected;
889 XO(
"Select one or more files"),
893 wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER);
901 const auto &saveType = fileTypes[ index ];
906 if (dialogResult == wxID_OK) {
920 const wxFileName newProjPathName(projPathName);
922 iter = std::find_if( start, finish,
926 if (iter != finish) {
928 XO(
"%s is already open in another window.")
929 .Format( newProjPathName.GetName() );
930 wxLogError(errMsg.Translation());
933 XO(
"Error Opening Project"),
941 const FilePath &fileNameArg,
bool addtohistory)
961 if (fileName.Lower().EndsWith(
wxT(
".aup3.bak")))
965"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."),
966 XO(
"Warning - Backup File Detected"),
972 if (!::wxFileExists(fileName)) {
974 XO(
"Could not open file: %s").
Format( fileName ),
975 XO(
"Error Opening File"),
983 wxFFile ff(fileName,
wxT(
"rb"));
985 auto cleanup =
finally([&]
993 if (!ff.IsOpened()) {
995 XO(
"Could not open file: %s").
Format( fileName ),
996 XO(
"Error opening file"),
1003 auto numRead = ff.Read(buf, 6);
1006 XO(
"File may be invalid or corrupted: \n%s").
Format( fileName ),
1007 XO(
"Error Opening File or Project"),
1013 if (wxStrncmp(buf,
"SQLite", 6) != 0)
1016#ifdef EXPERIMENTAL_DRAG_DROP_PLUG_INS
1025 auto &
project = chooser(
false);
1031 if (!fileName.AfterLast(
'.').IsSameAs(
wxT(
"lof"),
false))
1042 XO(
"Project resides on FAT formatted drive.\n"
1043 "Copy it to another drive to open it.")))
1048 auto &
project = chooser(
true);
1061 for (
auto iter =
tracks.begin(); iter !=
tracks.end();) {
1062 auto t = (*iter++)->SharedPointer();
1063 const auto linkType = t->GetLinkType();
1067 if (!t->LinkConsistencyFix()) {
1068 onError(
XO(
"A channel of a stereo track was missing."));
1069 unlinkedTrack =
nullptr;
1071 if (!unlinkedTrack) {
1073 t->NChannels() == 1) {
1076 assert(t->GetOwner().get() == &
tracks);
1081 iter =
tracks.Find(t.get());
1088 if (
const auto left =
dynamic_cast<WaveTrack*
>(unlinkedTrack.get())) {
1089 if (
const auto right =
dynamic_cast<WaveTrack*
>(t.get())) {
1091 assert(right->GetOwner().get() == &
tracks);
1092 left->SetPan(-1.0f);
1093 right->SetPan(1.0f);
1097 if(left->GetRate() != right->GetRate())
1099 onUnlink(
XO(
"This project contained stereo tracks with different sample rates per channel."));
1100 if(left->GetSampleFormat() != right->GetSampleFormat())
1102 onUnlink(
XO(
"This project contained stereo tracks with different sample formats in channels."));
1104 onUnlink(
XO(
"This project contained stereo tracks with non-aligned content."));
1107 unlinkedTrack =
nullptr;
1110 if (
const auto message = t->GetErrorOpening()) {
1112 wxT(
"Track %s had error reading clip values from project file."),
1120 const FilePath &fileName,
bool addtohistory)
1135 const bool bParseSuccess = results.parseSuccess;
1136 const auto &errorStr = results.errorString;
1137 const bool err = results.trackError;
1139 if (bParseSuccess && !err) {
1144 viewport.HandleResize();
1145 trackPanel.Refresh(
false);
1149 trackPanel.Update();
1157 if (bParseSuccess && !err) {
1158 if (projectFileIO.IsRecovered())
1161 history.PushState(
XO(
"Project was recovered"),
XO(
"Recover"));
1181 wxLogError(
wxT(
"Could not parse file \"%s\". \nError: %s"), fileName, errorStr.Debug());
1184 XO(
"Error Opening Project"),
1201 std::vector<Track*> results;
1205 wxFileName
fn(fileName);
1207 bool initiallyEmpty =
tracks.empty();
1209 wxString trackNameBase =
fn.GetName();
1215 const bool projectHasSolo =
1217 if (projectHasSolo) {
1218 for (
auto &group : newTracks)
1219 if (
auto pTrack =
dynamic_cast<PlayableTrack*
>(group.get()))
1220 pTrack->SetMute(
true);
1223 for (
auto &group : newTracks) {
1224 if (
auto pTrack =
dynamic_cast<WaveTrack*
>(group.get()))
1225 results.push_back(pTrack);
1234 const bool useSuffix = results.size() > 1;
1236 for (
const auto &newTrack : results) {
1238 newTrack->SetSelected(
true);
1241 newTrack->SetName(
XC(
"%s %d",
"clip name template")
1242 .Format(trackNameBase, i + 1).Translation());
1244 newTrack->SetName(trackNameBase);
1246 newTrack->TypeSwitch([&](
WaveTrack &wt) {
1249 const auto trackName = wt.
GetName();
1250 for (
const auto &interval : wt.
Intervals())
1251 interval->SetName(trackName);
1255 history.PushState(
XO(
"Imported '%s'").Format( fileName ),
1258#if defined(__WXGTK__)
1264 wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI | wxEVT_CATEGORY_USER_INPUT);
1269 if (initiallyEmpty && projectFileIO.IsTemporary()) {
1271 project.SetInitialImportPath(
fn.GetPath());
1272 projectFileIO.SetProjectTitle();
1286 if (!projectFileIO.LoadProject(fileName,
false))
1290 for (
const Track *pTrack : srcTracks)
1291 pTrack->PasteInto(dest, destTracks);
1311 mImportFileHandle = &importFileHandle;
1317 if (ImportDlg.ShowModal() == wxID_CANCEL)
1328 constexpr double ProgressSteps { 1000.0 };
1329 if(!mProgressDialog)
1331 wxFileName ff( mImportFileHandle->GetFilename() );
1332 auto title =
XO(
"Importing %s").Format( mImportFileHandle->GetFileDescription() );
1335 auto result = mProgressDialog->Poll(progress * ProgressSteps, ProgressSteps);
1337 mImportFileHandle->Cancel();
1339 mImportFileHandle->Stop();
1344 mProgressDialog.reset();
1345 if(result == ImportResult::Error)
1347 auto message = mImportFileHandle->GetErrorMessage();
1348 if(!message.empty())
1365 return Import(std::vector<FilePath> { fileName }, addToHistory);
1371 const std::vector<std::shared_ptr<ClipMirAudioReader>>& readers,
1374 const auto isBeatsAndMeasures =
project.ViewIsBeatsAndMeasures();
1375 const auto projectTempo =
project.GetTempo();
1379 XO(
"Music Information Retrieval"),
XO(
"Analyzing imported audio"),
1382 const auto reportProgress = [&](
double progressFraction) {
1383 const auto result = progress->Poll(
1384 (count + progressFraction) / readers.size() * 1000, 1000);
1389 std::vector<std::shared_ptr<MIR::AnalyzedAudioClip>> analyzedClips;
1390 analyzedClips.reserve(readers.size());
1392 readers.begin(), readers.end(), std::back_inserter(analyzedClips),
1393 [&](
const std::shared_ptr<ClipMirAudioReader>& reader) {
1394 const MIR::ProjectSyncInfoInput input {
1395 *reader, reader->filename, reader->tags, reportProgress,
1396 projectTempo, projectWasEmpty, isBeatsAndMeasures,
1400 return std::make_shared<AnalyzedWaveClip>(reader, syncInfo);
1402 return analyzedClips;
1407 const std::vector<FilePath>& fileNames,
bool addToHistory)
1409 const auto projectWasEmpty =
1411 std::vector<std::shared_ptr<ClipMirAudioReader>> resultingReaders;
1412 const auto success = std::all_of(
1413 fileNames.begin(), fileNames.end(), [&](
const FilePath& fileName) {
1414 std::shared_ptr<ClipMirAudioReader> resultingReader;
1415 const auto success = Import(fileName, addToHistory, resultingReader);
1416 if (success && resultingReader)
1417 resultingReaders.push_back(std::move(resultingReader));
1420 if (success && !resultingReaders.empty())
1422 const auto pProj =
mProject.shared_from_this();
1425 const auto analyzedClips =
1435 const FilePath& fileName,
bool addToHistory,
1436 std::shared_ptr<ClipMirAudioReader>& resultingReader)
1445#ifdef EXPERIMENTAL_IMPORT_AUP3
1447 if (fileName.AfterLast(
'.').IsSameAs(
wxT(
"aup3"),
false)) {
1453 if (initiallyEmpty && projectFileIO.IsTemporary()) {
1454 wxFileName
fn(fileName);
1456 project.SetInitialImportPath(
fn.GetPath());
1457 projectFileIO.SetProjectTitle();
1460 history.PushState(
XO(
"Imported '%s'").
Format(fileName),
XO(
"Import"));
1467 errorMessage = projectFileIO.GetLastError();
1468 if (errorMessage.
empty()) {
1469 errorMessage =
XO(
"Failed to import project");
1474 XO(
"Error Importing"),
1475 errorMessage,
wxT(
"Importing_Audio"));
1484 bool committed =
false;
1485 auto cleanup =
finally([&]{
1489 auto newTags = oldTags->Duplicate();
1492#ifndef EXPERIMENTAL_IMPORT_AUP3
1494 if (fileName.AfterLast(
'.').IsSameAs(
wxT(
"aup3"),
false)) {
1496 XO(
"Error Importing"),
1497 XO(
"Cannot import AUP3 format. Use File > Open instead"),
1503 ImportProgress importProgress(
project);
1504 std::optional<LibFileFormats::AcidizerTags> acidTags;
1507 newTracks, newTags.get(), acidTags, errorMessage);
1508 if (!errorMessage.
empty()) {
1512 XO(
"Error Importing"), errorMessage,
wxT(
"Importing_Audio"));
1518 for (
auto track : newTracks)
1521 if (newTracks.size() == 1)
1523 if (
const auto waveTrack =
dynamic_cast<WaveTrack*
>(newTracks[0].get()))
1525 std::move(acidTags), fileName.ToStdString(),
1539 if (fileName.AfterLast(
'.').IsSameAs(
wxT(
"lof"),
false)) {
1549 if (fileName.AfterLast(
'.').IsSameAs(
wxT(
"aup"),
false)) {
1552 if (initiallyEmpty && projectFileIO.IsTemporary()) {
1553 wxFileName
fn(fileName);
1555 project.SetInitialImportPath(
fn.GetPath());
1556 projectFileIO.SetProjectTitle();
1561 history.PushState(
XO(
"Imported '%s'").
Format( fileName ),
XO(
"Import"));
1586 S.StartVerticalLay(
true);
1588 S.AddFixedText(text,
false, 500);
1594 FindWindowById(wxID_YES,
this)->Bind(wxEVT_BUTTON, &CompactDialog::OnYes,
this);
1595 FindWindowById(wxID_NO,
this)->Bind(wxEVT_BUTTON, &CompactDialog::OnNo,
this);
1596 FindWindowById(wxID_HELP,
this)->Bind(wxEVT_BUTTON, &CompactDialog::OnGetURL,
this);
1603 void OnYes(wxCommandEvent &WXUNUSED(evt))
1608 void OnNo(wxCommandEvent &WXUNUSED(evt))
1626 bool isBatch =
project.mBatchMode > 0;
1629 projectFileIO.ReopenProject();
1631 auto savedState = undoManager.GetSavedState();
1632 const auto currentState = undoManager.GetCurrentState();
1633 if (savedState < 0) {
1634 undoManager.StateSaved();
1635 savedState = undoManager.GetSavedState();
1636 if (savedState < 0) {
1641 const auto least = std::min<size_t>(savedState, currentState);
1642 const auto greatest = std::max<size_t>(savedState, currentState);
1643 std::vector<const TrackList*> trackLists;
1646 trackLists.push_back(pTracks);
1648 undoManager.VisitStates(
fn, least, 1 + least);
1649 if (least != greatest)
1650 undoManager.VisitStates(
fn, greatest, 1 + greatest);
1652 int64_t total = projectFileIO.GetTotalUsage();
1653 int64_t used = projectFileIO.GetCurrentUsage(trackLists);
1655 auto before = wxFileName::GetSize(projectFileIO.GetFileName());
1658 XO(
"Compacting this project will free up disk space by removing unused bytes within the file.\n\n"
1659 "There is %s of free disk space and this project is currently using %s.\n"
1661 "If you proceed, the current Undo/Redo History and clipboard contents will be discarded "
1662 "and you will recover approximately %s of disk space.\n"
1664 "Do you want to continue?")
1668 if (isBatch || dlg.ShowModal() == wxYES)
1671 undoManager.RemoveStates(1 + greatest, undoManager.GetNumStates());
1674 if (least < greatest)
1675 undoManager.RemoveStates(least + 1, greatest);
1678 undoManager.RemoveStates(0, least);
1681 if (&
mProject == clipboard.Project().lock().get())
1686 auto before = wxFileName::GetSize(projectFileIO.GetFileName());
1688 projectFileIO.Compact(trackLists,
true);
1690 auto after = wxFileName::GetSize(projectFileIO.GetFileName());
1695 XO(
"Compacting actually freed %s of disk space.")
1697 XO(
"Compact Project"));
1700 undoManager.RenameState( undoManager.GetCurrentState(),
1701 XO(
"Compacted project file"),
1711 bShowProjectNumbers ? pProject->GetProjectNumber() : -1 );
1719 if( window.IsIconized() )
1730 return ptr->GetProjectName().empty();
1735 _(
"[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.
int ShowWarningDialog(wxWindow *parent, const wxString &internalDialogName, const TranslatableString &message, bool showCancelButton, const TranslatableString &footer)
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 SaveCopy(const FilePath &fileName=wxT(""))
bool Import(const std::vector< FilePath > &fileNames, bool addToHistory=true)
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)
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)
bool UnsavedChanges() const
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 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.