Bug 1600: Should keep progress dialog visible throughout Exp. Multi

This commit is contained in:
Paul Licameli 2018-01-25 15:58:37 -05:00
parent f5737be02c
commit d4b21bb33e
13 changed files with 124 additions and 58 deletions

View File

@ -256,6 +256,18 @@ std::unique_ptr<Mixer> ExportPlugin::CreateMixer(const WaveTrackConstArray &inpu
highQuality, mixerSpec);
}
void ExportPlugin::InitProgress(std::unique_ptr<ProgressDialog> &pDialog,
const wxString &title, const wxString &message)
{
if (!pDialog)
pDialog = std::make_unique<ProgressDialog>( title, message );
else {
pDialog->SetTitle( title );
pDialog->SetMessage( message );
pDialog->Reinit();
}
}
//----------------------------------------------------------------------------
// Export
//----------------------------------------------------------------------------
@ -849,7 +861,9 @@ bool Exporter::ExportTracks()
}
} );
std::unique_ptr<ProgressDialog> pDialog;
auto result = mPlugins[mFormat]->Export(mProject,
pDialog,
mChannels,
mActualName.GetFullPath(),
mSelectedOnly,

View File

@ -30,6 +30,7 @@ class DirManager;
class WaveTrack;
class TrackList;
class MixerSpec;
class ProgressDialog;
class TimeTrack;
class Mixer;
using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >;
@ -97,6 +98,9 @@ public:
/** \brief called to export audio into a file.
*
* @param pDialog To be initialized with pointer to a NEW ProgressDialog if
* it was null, otherwise gives an existing dialog to be reused
* (working around a problem in wxWidgets for Mac; see bug 1600)
* @param selectedOnly Set to true if all tracks should be mixed, to false
* if only the selected tracks should be mixed and exported.
* @param metadata A Tags object that will over-ride the one in *project and
@ -114,6 +118,7 @@ public:
* ProgressResult::Stopped
*/
virtual ProgressResult Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectedOnly,
@ -131,6 +136,10 @@ protected:
double outRate, sampleFormat outFormat,
bool highQuality = true, MixerSpec *mixerSpec = NULL);
// Create or recycle a dialog.
static void InitProgress(std::unique_ptr<ProgressDialog> &pDialog,
const wxString &title, const wxString &message);
private:
FormatInfoArray mFormatInfos;
};

View File

@ -287,6 +287,7 @@ public:
wxWindow *OptionsCreate(wxWindow *parent, int format) override;
ProgressResult Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectedOnly,
@ -309,6 +310,7 @@ ExportCL::ExportCL()
}
ProgressResult ExportCL::Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectionOnly,
@ -448,10 +450,11 @@ ProgressResult ExportCL::Export(AudacityProject *project,
} );
// Prepare the progress display
ProgressDialog progress(_("Export"),
selectionOnly ?
_("Exporting the selected audio using command-line encoder") :
_("Exporting the audio using command-line encoder"));
InitProgress( pDialog, _("Export"),
selectionOnly
? _("Exporting the selected audio using command-line encoder")
: _("Exporting the audio using command-line encoder") );
auto &progress = *pDialog;
// Start piping the mixed data to the command
while (updateResult == ProgressResult::Success && process.IsActive() && os->IsOk()) {

View File

@ -141,6 +141,7 @@ public:
///\param subformat index of export type
///\return true if export succeded
ProgressResult Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectedOnly,
@ -849,8 +850,10 @@ bool ExportFFmpeg::EncodeAudioFrame(int16_t *pFrame, size_t frameSize)
ProgressResult ExportFFmpeg::Export(AudacityProject *project,
unsigned channels, const wxString &fName,
bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, const Tags *metadata, int subformat)
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels, const wxString &fName,
bool selectionOnly, double t0, double t1,
MixerSpec *mixerSpec, const Tags *metadata, int subformat)
{
if (!CheckFFmpegPresence())
return ProgressResult::Cancelled;
@ -901,10 +904,13 @@ ProgressResult ExportFFmpeg::Export(AudacityProject *project,
auto updateResult = ProgressResult::Success;
{
ProgressDialog progress(wxFileName(fName).GetName(),
selectionOnly ?
wxString::Format(_("Exporting selected audio as %s"), ExportFFmpegOptions::fmts[mSubFormat].Description()) :
wxString::Format(_("Exporting the audio as %s"), ExportFFmpegOptions::fmts[mSubFormat].Description()));
InitProgress( pDialog, wxFileName(fName).GetName(),
selectionOnly
? wxString::Format(_("Exporting selected audio as %s"),
ExportFFmpegOptions::fmts[mSubFormat].Description())
: wxString::Format(_("Exporting the audio as %s"),
ExportFFmpegOptions::fmts[mSubFormat].Description()) );
auto &progress = *pDialog;
while (updateResult == ProgressResult::Success) {
auto pcmNumSamples = mixer->Process(pcmBufferSize);

View File

@ -191,6 +191,7 @@ public:
wxWindow *OptionsCreate(wxWindow *parent, int format) override;
ProgressResult Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectedOnly,
@ -222,6 +223,7 @@ ExportFLAC::ExportFLAC()
}
ProgressResult ExportFLAC::Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned numChannels,
const wxString &fName,
bool selectionOnly,
@ -354,10 +356,11 @@ ProgressResult ExportFLAC::Export(AudacityProject *project,
ArraysOf<FLAC__int32> tmpsmplbuf{ numChannels, SAMPLES_PER_RUN, true };
ProgressDialog progress(wxFileName(fName).GetName(),
selectionOnly ?
_("Exporting the selected audio as FLAC") :
_("Exporting the audio as FLAC"));
InitProgress( pDialog, wxFileName(fName).GetName(),
selectionOnly
? _("Exporting the selected audio as FLAC")
: _("Exporting the audio as FLAC") );
auto &progress = *pDialog;
while (updateResult == ProgressResult::Success) {
auto samplesThisRun = mixer->Process(SAMPLES_PER_RUN);

View File

@ -174,6 +174,7 @@ public:
wxWindow *OptionsCreate(wxWindow *parent, int format) override;
ProgressResult Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectedOnly,
@ -204,6 +205,7 @@ ExportMP2::ExportMP2()
}
ProgressResult ExportMP2::Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels, const wxString &fName,
bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, const Tags *metadata,
int WXUNUSED(subformat))
@ -272,10 +274,13 @@ ProgressResult ExportMP2::Export(AudacityProject *project,
stereo ? 2 : 1, pcmBufferSize, true,
rate, int16Sample, true, mixerSpec);
ProgressDialog progress(wxFileName(fName).GetName(),
selectionOnly ?
wxString::Format(_("Exporting selected audio at %ld kbps"), bitrate) :
wxString::Format(_("Exporting the audio at %ld kbps"), bitrate));
InitProgress( pDialog, wxFileName(fName).GetName(),
selectionOnly
? wxString::Format(_("Exporting selected audio at %ld kbps"),
bitrate)
: wxString::Format(_("Exporting the audio at %ld kbps"),
bitrate) );
auto &progress = *pDialog;
while (updateResult == ProgressResult::Success) {
auto pcmNumSamples = mixer->Process(pcmBufferSize);

View File

@ -1610,6 +1610,7 @@ public:
wxWindow *OptionsCreate(wxWindow *parent, int format) override;
ProgressResult Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectedOnly,
@ -1670,6 +1671,7 @@ int ExportMP3::SetNumExportChannels()
ProgressResult ExportMP3::Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectionOnly,
@ -1858,7 +1860,8 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
brate);
}
ProgressDialog progress(wxFileName(fName).GetName(), title);
InitProgress( pDialog, wxFileName(fName).GetName(), title );
auto &progress = *pDialog;
while (updateResult == ProgressResult::Success) {
auto blockLen = mixer->Process(inSamples);

View File

@ -749,6 +749,7 @@ ProgressResult ExportMultiple::ExportMultipleByLabel(bool byName,
ExportKit activeSetting; // pointer to the settings in use for this export
/* Go round again and do the exporting (so this run is slow but
* non-interactive) */
std::unique_ptr<ProgressDialog> pDialog;
for (count = 0; count < numFiles; count++) {
/* get the settings to use for the export from the array */
activeSetting = exportSettings[count];
@ -757,7 +758,8 @@ ProgressResult ExportMultiple::ExportMultipleByLabel(bool byName,
continue;
// Export it
ok = DoExport(channels, activeSetting.destfile, false, activeSetting.t0, activeSetting.t1, activeSetting.filetags);
ok = DoExport(pDialog, channels, activeSetting.destfile, false,
activeSetting.t0, activeSetting.t1, activeSetting.filetags);
if (ok != ProgressResult::Success && ok != ProgressResult::Stopped) {
break;
}
@ -887,6 +889,7 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName,
// loop
int count = 0; // count the number of sucessful runs
ExportKit activeSetting; // pointer to the settings in use for this export
std::unique_ptr<ProgressDialog> pDialog;
for (tr = iter.First(mTracks); tr != NULL; tr = iter.Next()) {
// Want only non-muted wave tracks.
@ -918,7 +921,9 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName,
tr2->SetSelected(true);
// Export the data. "channels" are per track.
ok = DoExport(activeSetting.channels, activeSetting.destfile, true, activeSetting.t0, activeSetting.t1, activeSetting.filetags);
ok = DoExport(pDialog,
activeSetting.channels, activeSetting.destfile, true,
activeSetting.t0, activeSetting.t1, activeSetting.filetags);
// Stop if an error occurred
if (ok != ProgressResult::Success && ok != ProgressResult::Stopped) {
@ -932,7 +937,8 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName,
return ok ;
}
ProgressResult ExportMultiple::DoExport(unsigned channels,
ProgressResult ExportMultiple::DoExport(std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxFileName &inName,
bool selectedOnly,
double t0,
@ -1001,6 +1007,7 @@ ProgressResult ExportMultiple::DoExport(unsigned channels,
// Call the format export routine
success = mPlugins[mPluginIndex]->Export(mProject,
pDialog,
channels,
fullPath,
selectedOnly,

View File

@ -75,7 +75,8 @@ private:
* @param t1 End time for export
* @param tags Metadata to include in the file (if possible).
*/
ProgressResult DoExport(unsigned channels,
ProgressResult DoExport(std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxFileName &name,
bool selectedOnly,
double t0,

View File

@ -133,6 +133,7 @@ public:
wxWindow *OptionsCreate(wxWindow *parent, int format) override;
ProgressResult Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectedOnly,
@ -159,6 +160,7 @@ ExportOGG::ExportOGG()
}
ProgressResult ExportOGG::Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned numChannels,
const wxString &fName,
bool selectionOnly,
@ -281,10 +283,11 @@ ProgressResult ExportOGG::Export(AudacityProject *project,
numChannels, SAMPLES_PER_RUN, false,
rate, floatSample, true, mixerSpec);
ProgressDialog progress(wxFileName(fName).GetName(),
selectionOnly ?
_("Exporting the selected audio as Ogg Vorbis") :
_("Exporting the audio as Ogg Vorbis"));
InitProgress( pDialog, wxFileName(fName).GetName(),
selectionOnly
? _("Exporting the selected audio as Ogg Vorbis")
: _("Exporting the audio as Ogg Vorbis") );
auto &progress = *pDialog;
while (updateResult == ProgressResult::Success && !eos) {
float **vorbis_buffer = vorbis_analysis_buffer(&dsp, SAMPLES_PER_RUN);

View File

@ -319,6 +319,7 @@ public:
wxWindow *OptionsCreate(wxWindow *parent, int format) override;
ProgressResult Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned channels,
const wxString &fName,
bool selectedOnly,
@ -390,6 +391,7 @@ ExportPCM::ExportPCM()
* file type, or giving the user full control over libsndfile.
*/
ProgressResult ExportPCM::Export(AudacityProject *project,
std::unique_ptr<ProgressDialog> &pDialog,
unsigned numChannels,
const wxString &fName,
bool selectionOnly,
@ -489,12 +491,13 @@ ProgressResult ExportPCM::Export(AudacityProject *project,
info.channels, maxBlockLen, true,
rate, format, true, mixerSpec);
ProgressDialog progress(wxFileName(fName).GetName(),
selectionOnly ?
wxString::Format(_("Exporting the selected audio as %s"),
formatStr) :
wxString::Format(_("Exporting the audio as %s"),
formatStr));
InitProgress( pDialog, wxFileName(fName).GetName(),
selectionOnly
? wxString::Format(_("Exporting the selected audio as %s"),
formatStr)
: wxString::Format(_("Exporting the audio as %s"),
formatStr) );
auto &progress = *pDialog;
while (updateResult == ProgressResult::Success) {
sf_count_t samplesWritten;

View File

@ -997,7 +997,6 @@ END_EVENT_TABLE()
ProgressDialog::ProgressDialog()
: wxDialogWrapper()
{
Init();
}
ProgressDialog::ProgressDialog(const wxString & title,
@ -1006,8 +1005,6 @@ ProgressDialog::ProgressDialog(const wxString & title,
const wxString & sRemainingLabelText /* = wxEmptyString */)
: wxDialogWrapper()
{
Init();
Create(title, message, flags, sRemainingLabelText);
}
@ -1017,8 +1014,6 @@ ProgressDialog::ProgressDialog(const wxString & title,
const wxString & sRemainingLabelText /* = wxEmptyString */)
: wxDialogWrapper()
{
Init();
Create(title, columns, flags, sRemainingLabelText);
}
@ -1059,10 +1054,6 @@ ProgressDialog::~ProgressDialog()
void ProgressDialog::Init()
{
mLastValue = 0;
mDisable = NULL;
mIsTransparent = true;
// There's a problem where the focus is not returned to the window that had
// it before creating this object. The reason is because the focus events
// that are sent to the parent window after the wxWindowDisabler are created
@ -1082,6 +1073,34 @@ void ProgressDialog::Init()
#endif
}
void ProgressDialog::Reinit()
{
mLastValue = 0;
mStartTime = wxGetLocalTimeMillis().GetValue();
mLastUpdate = mStartTime;
mYieldTimer = mStartTime;
mCancel = false;
mStop = false;
// Because wxGTK is very sensitive about maintaining focus when
// this window is not shown, we always show it. But, since we
// want a 500ms delay before it's actually visible for those
// quick tasks, we show it as transparent. If the initial
// delay is exceeded, then we reset the dialog to full opacity.
SetTransparent(0);
mIsTransparent = true;
auto button = FindWindowById(wxID_CANCEL, this);
if (button)
button->Enable();
button = FindWindowById(wxID_OK, this);
if (button)
button->Enable();
wxDialogWrapper::Show(true);
}
// Add a NEW text column each time this is called.
void ProgressDialog::AddMessageAsColumn(wxBoxSizer * pSizer,
const MessageColumn & column,
@ -1138,6 +1157,8 @@ bool ProgressDialog::Create(const wxString & title,
int flags /* = pdlgDefaultFlags */,
const wxString & sRemainingLabelText /* = wxEmptyString */)
{
Init();
wxWindow *parent = GetParentForModalDialog(NULL, 0);
// Set this boolean to indicate if we are using the "Elapsed" labels
@ -1267,21 +1288,7 @@ bool ProgressDialog::Create(const wxString & title,
Centre(wxCENTER_FRAME | wxBOTH);
mStartTime = wxGetLocalTimeMillis().GetValue();
mLastUpdate = mStartTime;
mYieldTimer = mStartTime;
mCancel = false;
mStop = false;
// Because wxGTK is very sensitive about maintaining focus when
// this window is not shown, we always show it. But, since we
// want a 500ms delay before it's actually visible for those
// quick tasks, we show it as transparent. If the initial
// delay is exceeded, then we reset the dialog to full opacity.
SetTransparent(0);
mIsTransparent = true;
wxDialogWrapper::Show(true);
Reinit();
// Even though we won't necessarily show the dialog due to the 500ms
// delay, we MUST disable other windows/menus anyway since we run the risk

View File

@ -86,6 +86,8 @@ public:
int flags = pdlgDefaultFlags,
const wxString & sRemainingLabelText = wxEmptyString);
void Reinit();
protected:
bool Create(const wxString & title,
const MessageTable & columns,
@ -103,7 +105,7 @@ public:
void SetMessage(const wxString & message);
protected:
wxWindow *mHadFocus;
wxWeakRef<wxWindow> mHadFocus;
wxStaticText *mElapsed;
wxStaticText *mRemaining;