diff --git a/src/FileIO.cpp b/src/FileIO.cpp index 0b1b2c59e..edded2a30 100644 --- a/src/FileIO.cpp +++ b/src/FileIO.cpp @@ -15,25 +15,26 @@ #include #include #include +#include "wxFileNameWrapper.h" -FileIO::FileIO(const wxString & name, FileIOMode mode) -: mName(name), - mMode(mode), +FileIO::FileIO(const wxFileNameWrapper & name, FileIOMode mode) +: mMode(mode), mOpen(false) { wxString scheme; + auto path = name.GetFullPath(); if (mMode == FileIO::Input) { - mInputStream = std::make_unique(mName); + mInputStream = std::make_unique(path); if (mInputStream == NULL || !mInputStream->IsOk()) { - wxPrintf(wxT("Couldn't get input stream: %s\n"), name); + wxPrintf(wxT("Couldn't get input stream: %s\n"), path); return; } } else { - mOutputStream = std::make_unique(mName); + mOutputStream = std::make_unique(path); if (mOutputStream == NULL || !mOutputStream->IsOk()) { - wxPrintf(wxT("Couldn't get output stream: %s\n"), name); + wxPrintf(wxT("Couldn't get output stream: %s\n"), path); return; } } diff --git a/src/FileIO.h b/src/FileIO.h index a60235d53..a1ee7f2e4 100644 --- a/src/FileIO.h +++ b/src/FileIO.h @@ -16,6 +16,7 @@ class wxInputStream; class wxOutputStream; class wxFFileOutputStream; +class wxFileNameWrapper; class FileIO { @@ -27,7 +28,7 @@ class FileIO } FileIOMode; public: - FileIO(const wxString & name, FileIOMode mode); + FileIO(const wxFileNameWrapper & name, FileIOMode mode); // Calls Close() ~FileIO(); @@ -40,7 +41,6 @@ class FileIO wxOutputStream & Write(const void *buffer, size_t size); private: - wxString mName; FileIOMode mMode; std::unique_ptr mInputStream; std::unique_ptr mOutputStream; diff --git a/src/export/Export.cpp b/src/export/Export.cpp index d7c32a835..84d4885ba 100644 --- a/src/export/Export.cpp +++ b/src/export/Export.cpp @@ -282,6 +282,12 @@ void ExportPlugin::InitProgress(std::unique_ptr &pDialog, } } +void ExportPlugin::InitProgress(std::unique_ptr &pDialog, + const wxFileNameWrapper &title, const wxString &message) +{ + return InitProgress( pDialog, title.GetName(), message ); +} + //---------------------------------------------------------------------------- // Export //---------------------------------------------------------------------------- diff --git a/src/export/Export.h b/src/export/Export.h index e70953158..6a020187e 100644 --- a/src/export/Export.h +++ b/src/export/Export.h @@ -34,6 +34,7 @@ class ProgressDialog; class Mixer; using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >; enum class ProgressResult : unsigned; +class wxFileNameWrapper; class AUDACITY_DLL_API FormatInfo { @@ -123,7 +124,7 @@ public: virtual ProgressResult Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, @@ -144,6 +145,8 @@ protected: // Create or recycle a dialog. static void InitProgress(std::unique_ptr &pDialog, const wxString &title, const wxString &message); + static void InitProgress(std::unique_ptr &pDialog, + const wxFileNameWrapper &title, const wxString &message); private: std::vector mFormatInfos; diff --git a/src/export/ExportCL.cpp b/src/export/ExportCL.cpp index 914e14ba9..4843f4957 100644 --- a/src/export/ExportCL.cpp +++ b/src/export/ExportCL.cpp @@ -38,6 +38,7 @@ #include "../widgets/FileHistory.h" #include "../widgets/AudacityMessageBox.h" #include "../widgets/ProgressDialog.h" +#include "../wxFileNameWrapper.h" //---------------------------------------------------------------------------- @@ -293,7 +294,7 @@ public: ProgressResult Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, @@ -318,7 +319,7 @@ ExportCL::ExportCL() ProgressResult ExportCL::Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectionOnly, double t0, double t1, @@ -331,15 +332,17 @@ ProgressResult ExportCL::Export(AudacityProject *project, bool show; long rc; + const auto path = fName.GetFullPath(); + // Retrieve settings gPrefs->Read(wxT("/FileFormats/ExternalProgramShowOutput"), &show, false); cmd = gPrefs->Read(wxT("/FileFormats/ExternalProgramExportCommand"), wxT("lame - \"%f.mp3\"")); // Bug 2178 - users who don't know what they are doing will // now get a file extension of .wav appended to their ffmpeg filename // and therefore ffmpeg will be able to choose a file type. - if( cmd == wxT("ffmpeg -i - \"%f\"") && fName.Index( '.' )==wxNOT_FOUND) + if( cmd == wxT("ffmpeg -i - \"%f\"") && !fName.HasExt()) cmd.Replace( "%f", "%f.wav" ); - cmd.Replace(wxT("%f"), fName); + cmd.Replace(wxT("%f"), path); #if defined(__WXMSW__) // Give Windows a chance at finding lame command in the default location. @@ -384,7 +387,7 @@ ProgressResult ExportCL::Export(AudacityProject *project, if (!rc) { AudacityMessageBox(wxString::Format(_("Cannot export audio to %s"), - fName)); + path)); process.Detach(); process.CloseOutput(); diff --git a/src/export/ExportFFmpeg.cpp b/src/export/ExportFFmpeg.cpp index 5d0b9e19b..11cb4c179 100644 --- a/src/export/ExportFFmpeg.cpp +++ b/src/export/ExportFFmpeg.cpp @@ -41,6 +41,7 @@ function. #include "../Track.h" #include "../widgets/AudacityMessageBox.h" #include "../widgets/ProgressDialog.h" +#include "../wxFileNameWrapper.h" #include "Export.h" @@ -142,7 +143,7 @@ public: ProgressResult Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, @@ -159,7 +160,7 @@ private: AVStream * mEncAudioStream{}; // the output audio stream (may remain NULL) int mEncAudioFifoOutBufSiz{}; - wxString mName; + wxFileNameWrapper mName; int mSubFormat{}; int mBitRate{}; @@ -279,9 +280,10 @@ bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, const T // See if libavformat has modules that can write our output format. If so, mEncFormatDesc // will describe the functions used to write the format (used internally by libavformat) // and the default video/audio codecs that the format uses. - if ((mEncFormatDesc = av_guess_format(shortname, OSINPUT(mName), NULL)) == NULL) + const auto path = mName.GetFullPath(); + if ((mEncFormatDesc = av_guess_format(shortname, OSINPUT(path), NULL)) == NULL) { - AudacityMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't determine format description for file \"%s\"."), mName), + AudacityMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't determine format description for file \"%s\"."), path), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } @@ -298,12 +300,12 @@ bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, const T // Initialise the output format context. mEncFormatCtx->oformat = mEncFormatDesc; - memcpy(mEncFormatCtx->filename, OSINPUT(mName), strlen(OSINPUT(mName))+1); + memcpy(mEncFormatCtx->filename, OSINPUT(path), strlen(OSINPUT(path))+1); // At the moment Audacity can export only one audio stream if ((mEncAudioStream = avformat_new_stream(mEncFormatCtx.get(), NULL)) == NULL) { - AudacityMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't add audio stream to output file \"%s\"."), mName), + AudacityMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't add audio stream to output file \"%s\"."), path), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } @@ -326,9 +328,9 @@ bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, const T // Open the output file. if (!(mEncFormatDesc->flags & AVFMT_NOFILE)) { - if ((err = ufile_fopen(&mEncFormatCtx->pb, mName, AVIO_FLAG_WRITE)) < 0) + if ((err = ufile_fopen(&mEncFormatCtx->pb, path, AVIO_FLAG_WRITE)) < 0) { - AudacityMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't open output file \"%s\" to write. Error code is %d."), mName, err), + AudacityMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't open output file \"%s\" to write. Error code is %d."), path, err), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } @@ -354,7 +356,7 @@ bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, const T // Write headers to the output file. if ((err = avformat_write_header(mEncFormatCtx.get(), NULL)) < 0) { - AudacityMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't write headers to output file \"%s\". Error code is %d."), mName,err), + AudacityMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't write headers to output file \"%s\". Error code is %d."), path, err), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } @@ -858,7 +860,7 @@ bool ExportFFmpeg::EncodeAudioFrame(int16_t *pFrame, size_t frameSize) ProgressResult ExportFFmpeg::Export(AudacityProject *project, std::unique_ptr &pDialog, - unsigned channels, const wxString &fName, + unsigned channels, const wxFileNameWrapper &fName, bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, const Tags *metadata, int subformat) { @@ -908,7 +910,7 @@ ProgressResult ExportFFmpeg::Export(AudacityProject *project, auto updateResult = ProgressResult::Success; { - InitProgress( pDialog, wxFileName(fName).GetName(), + InitProgress( pDialog, fName, selectionOnly ? wxString::Format(_("Exporting selected audio as %s"), ExportFFmpegOptions::fmts[mSubFormat].description.Translation()) diff --git a/src/export/ExportFLAC.cpp b/src/export/ExportFLAC.cpp index 21e3f9807..e07eb372c 100644 --- a/src/export/ExportFLAC.cpp +++ b/src/export/ExportFLAC.cpp @@ -41,6 +41,7 @@ and libvorbis examples, Monty #include "../widgets/AudacityMessageBox.h" #include "../widgets/ProgressDialog.h" +#include "../wxFileNameWrapper.h" //---------------------------------------------------------------------------- // ExportFLACOptions Class @@ -215,7 +216,7 @@ public: ProgressResult Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, @@ -249,7 +250,7 @@ ExportFLAC::ExportFLAC() ProgressResult ExportFLAC::Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned numChannels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectionOnly, double t0, double t1, @@ -343,8 +344,9 @@ ProgressResult ExportFLAC::Export(AudacityProject *project, encoder.init(); #else wxFFile f; // will be closed when it goes out of scope - if (!f.Open(fName, wxT("w+b"))) { - AudacityMessageBox(wxString::Format(_("FLAC export couldn't open %s"), fName)); + const auto path = fName.GetFullPath(); + if (!f.Open(path, wxT("w+b"))) { + AudacityMessageBox(wxString::Format(_("FLAC export couldn't open %s"), path)); return ProgressResult::Cancelled; } @@ -377,7 +379,7 @@ ProgressResult ExportFLAC::Export(AudacityProject *project, ArraysOf tmpsmplbuf{ numChannels, SAMPLES_PER_RUN, true }; - InitProgress( pDialog, wxFileName(fName).GetName(), + InitProgress( pDialog, fName, selectionOnly ? _("Exporting the selected audio as FLAC") : _("Exporting the audio as FLAC") ); diff --git a/src/export/ExportMP2.cpp b/src/export/ExportMP2.cpp index 9570977f7..ae0bb47d1 100644 --- a/src/export/ExportMP2.cpp +++ b/src/export/ExportMP2.cpp @@ -209,7 +209,7 @@ public: ProgressResult Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, @@ -241,7 +241,7 @@ ExportMP2::ExportMP2() ProgressResult ExportMP2::Export(AudacityProject *project, std::unique_ptr &pDialog, - unsigned channels, const wxString &fName, + unsigned channels, const wxFileNameWrapper &fName, bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, const Tags *metadata, int WXUNUSED(subformat)) { @@ -307,7 +307,7 @@ ProgressResult ExportMP2::Export(AudacityProject *project, stereo ? 2 : 1, pcmBufferSize, true, rate, int16Sample, true, mixerSpec); - InitProgress( pDialog, wxFileName(fName).GetName(), + InitProgress( pDialog, fName, selectionOnly ? wxString::Format(_("Exporting selected audio at %ld kbps"), bitrate) diff --git a/src/export/ExportMP3.cpp b/src/export/ExportMP3.cpp index 7d05816e5..3200c667d 100644 --- a/src/export/ExportMP3.cpp +++ b/src/export/ExportMP3.cpp @@ -92,6 +92,7 @@ #include "../widgets/HelpSystem.h" #include "../widgets/AudacityMessageBox.h" #include "../widgets/ProgressDialog.h" +#include "../wxFileNameWrapper.h" #include "Export.h" @@ -1657,7 +1658,7 @@ public: ProgressResult Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, @@ -1717,7 +1718,7 @@ int ExportMP3::SetNumExportChannels() ProgressResult ExportMP3::Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectionOnly, double t0, double t1, @@ -1841,7 +1842,7 @@ ProgressResult ExportMP3::Export(AudacityProject *project, metadata = &Tags::Get( *project ); // Open file for writing - wxFFile outFile(fName, wxT("w+b")); + wxFFile outFile(fName.GetFullPath(), wxT("w+b")); if (!outFile.IsOpened()) { AudacityMessageBox(_("Unable to open target file for writing")); return ProgressResult::Cancelled; @@ -1898,7 +1899,7 @@ ProgressResult ExportMP3::Export(AudacityProject *project, brate); } - InitProgress( pDialog, wxFileName(fName).GetName(), title ); + InitProgress( pDialog, fName, title ); auto &progress = *pDialog; while (updateResult == ProgressResult::Success) { diff --git a/src/export/ExportOGG.cpp b/src/export/ExportOGG.cpp index 7b9dbd34b..52ca0a50d 100644 --- a/src/export/ExportOGG.cpp +++ b/src/export/ExportOGG.cpp @@ -134,7 +134,7 @@ public: ProgressResult Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, @@ -163,7 +163,7 @@ ExportOGG::ExportOGG() ProgressResult ExportOGG::Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned numChannels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectionOnly, double t0, double t1, @@ -281,7 +281,7 @@ ProgressResult ExportOGG::Export(AudacityProject *project, numChannels, SAMPLES_PER_RUN, false, rate, floatSample, true, mixerSpec); - InitProgress( pDialog, wxFileName(fName).GetName(), + InitProgress( pDialog, fName, selectionOnly ? _("Exporting the selected audio as Ogg Vorbis") : _("Exporting the audio as Ogg Vorbis") ); diff --git a/src/export/ExportPCM.cpp b/src/export/ExportPCM.cpp index 7be51d38e..2ed4dfdad 100644 --- a/src/export/ExportPCM.cpp +++ b/src/export/ExportPCM.cpp @@ -34,6 +34,7 @@ #include "../widgets/AudacityMessageBox.h" #include "../widgets/ErrorDialog.h" #include "../widgets/ProgressDialog.h" +#include "../wxFileNameWrapper.h" #include "Export.h" @@ -330,7 +331,7 @@ public: ProgressResult Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned channels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, @@ -347,7 +348,8 @@ private: void ReportTooBigError(wxWindow * pParent); ArrayOf AdjustString(const wxString & wxStr, int sf_format); bool AddStrings(AudacityProject *project, SNDFILE *sf, const Tags *tags, int sf_format); - bool AddID3Chunk(wxString fName, const Tags *tags, int sf_format); + bool AddID3Chunk( + const wxFileNameWrapper &fName, const Tags *tags, int sf_format); }; @@ -424,7 +426,7 @@ void ExportPCM::ReportTooBigError(wxWindow * pParent) ProgressResult ExportPCM::Export(AudacityProject *project, std::unique_ptr &pDialog, unsigned numChannels, - const wxString &fName, + const wxFileNameWrapper &fName, bool selectionOnly, double t0, double t1, @@ -492,7 +494,8 @@ ProgressResult ExportPCM::Export(AudacityProject *project, return ProgressResult::Cancelled; } - if (f.Open(fName, wxFile::write)) { + const auto path = fName.GetFullPath(); + if (f.Open(path, wxFile::write)) { // Even though there is an sf_open() that takes a filename, use the one that // takes a file descriptor since wxWidgets can open a file with a Unicode name and // libsndfile can't (under Windows). @@ -503,7 +506,7 @@ ProgressResult ExportPCM::Export(AudacityProject *project, if (!sf) { AudacityMessageBox(wxString::Format(_("Cannot export audio to %s"), - fName)); + path)); return ProgressResult::Cancelled; } // Retrieve tags if not given a set @@ -550,7 +553,7 @@ ProgressResult ExportPCM::Export(AudacityProject *project, info.channels, maxBlockLen, true, rate, format, true, mixerSpec); - InitProgress( pDialog, wxFileName(fName).GetName(), + InitProgress( pDialog, fName, selectionOnly ? wxString::Format(_("Exporting the selected audio as %s"), formatStr) @@ -785,7 +788,8 @@ struct id3_tag_deleter { using id3_tag_holder = std::unique_ptr; #endif -bool ExportPCM::AddID3Chunk(wxString fName, const Tags *tags, int sf_format) +bool ExportPCM::AddID3Chunk( + const wxFileNameWrapper &fName, const Tags *tags, int sf_format) { #ifdef USE_LIBID3TAG id3_tag_holder tp { id3_tag_new() }; @@ -882,7 +886,7 @@ bool ExportPCM::AddID3Chunk(wxString fName, const Tags *tags, int sf_format) id3_tag_render(tp.get(), buffer.get()); - wxFFile f(fName, wxT("r+b")); + wxFFile f(fName.GetFullPath(), wxT("r+b")); if (f.IsOpened()) { wxUint32 sz;