1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-24 16:20:05 +02:00

Introduce further enhancement of the Timer Recording process:

* Disk space warning if the recording potentially will not fit in disk space available.
* ProgressDialog enhancements that allow the Stop/Cancel button to be confirmed and the elapsed time to be hidden.
* Messages enhanced to clearly show the actions being taken.
This commit is contained in:
tip2tail 2016-03-30 23:46:15 +01:00 committed by James Crook
parent 726efcf5c8
commit 6686d0e314
7 changed files with 257 additions and 80 deletions

View File

@ -6316,8 +6316,7 @@ void AudacityProject::OnTimerRecord()
// it is now safer to disable Timer Recording when there is more than // it is now safer to disable Timer Recording when there is more than
// one open project. // one open project.
if (GetOpenProjectCount() > 1) { if (GetOpenProjectCount() > 1) {
wxMessageBox(_("Timer Recording cannot be used with more than one open project.\n\n\ wxMessageBox(_("Timer Recording cannot be used with more than one open project.\n\nPlease close any additional projects and try again."),
Please close any additional projects and try again."),
_("Timer Recording"), _("Timer Recording"),
wxICON_INFORMATION | wxOK); wxICON_INFORMATION | wxOK);
return; return;

View File

@ -5254,3 +5254,36 @@ bool AudacityProject::ProjectHasTracks() {
bool bHasTracks = (iter2.First() != NULL); bool bHasTracks = (iter2.First() != NULL);
return bHasTracks; return bHasTracks;
} }
// MY: This routine will give an estimate of how many
// minutes of recording time we have available.
// This is called from TimerRecordDialog::OnOK() to allow
// the user to resolve a potential disk space issue before
// Timer Recording starts.
// The calculations made are based on the user's current
// preferences.
int AudacityProject::GetEstimatedRecordingMinsLeftOnDisk() {
// Obtain the current settings
sampleFormat oCaptureFormat = (sampleFormat)
gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample);
long lCaptureChannels;
gPrefs->Read(wxT("/AudioIO/RecordChannels"), &lCaptureChannels, 2L);
// Find out how much free space we have on disk
wxLongLong lFreeSpace = mDirManager->GetFreeDiskSpace();
if (lFreeSpace < 0) {
return 0;
}
// Calculate the remaining time
double dRecTime = 0.0;
dRecTime = lFreeSpace.GetHi() * 4294967296.0 + lFreeSpace.GetLo();
dRecTime /= SAMPLE_SIZE_DISK(oCaptureFormat);
dRecTime /= lCaptureChannels;
dRecTime /= GetRate();
// Convert to minutes before returning
int iRecMins = (int)(dRecTime / 60.0);
return iRecMins;
}

View File

@ -283,6 +283,9 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
bool ProjectHasTracks(); bool ProjectHasTracks();
// Routine to estimate how many minutes of recording time are left on disk
int GetEstimatedRecordingMinsLeftOnDisk();
#include "Menus.h" #include "Menus.h"
CommandManager *GetCommandManager() { return &mCommandManager; } CommandManager *GetCommandManager() { return &mCommandManager; }

View File

@ -371,6 +371,33 @@ void TimerRecordDialog::OnOK(wxCommandEvent& WXUNUSED(event))
} }
} }
// MY: Estimate here if we have enough disk space to
// complete this Timer Recording.
// If we dont think there is enough space then ask the user
// if they want to continue.
// We don't stop the user from starting the recording
// as its possible that they plan to free up some
// space before the recording begins
AudacityProject* pProject = GetActiveProject();
// How many minutes do we have left on the recording?
int iMinsLeft = pProject->GetEstimatedRecordingMinsLeftOnDisk();
// How many minutes will this recording require?
int iMinsRecording = m_TimeSpan_Duration.GetMinutes();
// Do we have enough space?
if (iMinsRecording >= iMinsLeft) {
wxMessageDialog dlgMessage(NULL,
_("You may not have enough free disk space to complete this timer recording, based on your current settings.\n\nDo you wish to continue?"),
_("Timer Recording Disk Space Warning"),
wxYES_NO | wxNO_DEFAULT | wxICON_WARNING);
if (dlgMessage.ShowModal() != wxID_YES) {
// User decided not to continue - bail out!
return;
}
}
m_timer.Stop(); // Don't need to keep updating m_DateTime_Start to prevent backdating. m_timer.Stop(); // Don't need to keep updating m_DateTime_Start to prevent backdating.
this->EndModal(wxID_OK); this->EndModal(wxID_OK);
wxLongLong duration = m_TimeSpan_Duration.GetSeconds(); wxLongLong duration = m_TimeSpan_Duration.GetSeconds();
@ -465,17 +492,26 @@ int TimerRecordDialog::RunWaitDialog()
pProject->OnRecord(); pProject->OnRecord();
bool bIsRecording = true; bool bIsRecording = true;
wxString strMsg = wxString sPostAction = m_pTimerAfterCompleteChoiceCtrl->GetString(m_pTimerAfterCompleteChoiceCtrl->GetSelection());
_("Recording start") + (wxString)wxT(":\t\t") wxString strMsg;
+ GetDisplayDate(m_DateTime_Start) + wxT("\n") + _("Recording end") strMsg.Printf(_("Recording start:\t\t\t%s\n") +
+ wxT(":\t\t") + GetDisplayDate(m_DateTime_End) + wxT("\n") _("Recording end:\t\t\t%s\n") +
+ _("Duration") + wxT(":\t\t") + m_TimeSpan_Duration.Format(); _("Duration:\t\t\t%s\n\n") +
_("Automatic Save Enabled:\t\t%s\n") +
_("Automatic Export Enabled:\t\t%s\n") +
_("Post Timer Recording Action:\t%s"),
GetDisplayDate(m_DateTime_Start).c_str(),
m_TimeSpan_Duration.Format(),
GetDisplayDate(m_DateTime_End).c_str(),
(m_bAutoSaveEnabled ? _("Yes") : _("No")),
(m_bAutoExportEnabled ? _("Yes") : _("No")),
sPostAction);
TimerProgressDialog TimerProgressDialog
progress(m_TimeSpan_Duration.GetMilliseconds().GetValue(), progress(m_TimeSpan_Duration.GetMilliseconds().GetValue(),
_("Audacity Timer Record Progress"), _("Audacity Timer Record Progress"),
strMsg, strMsg,
pdlgHideCancelButton); pdlgHideCancelButton | pdlgConfirmStopCancel);
// Make sure that start and end time are updated, so we always get the full // Make sure that start and end time are updated, so we always get the full
// duration, even if there's some delay getting here. // duration, even if there's some delay getting here.
@ -593,11 +629,20 @@ int TimerRecordDialog::ExecutePostRecordActions(bool bWasStopped) {
// MY: Lets do some actions that only apply to Exit/Restart/Shutdown // MY: Lets do some actions that only apply to Exit/Restart/Shutdown
if (iPostRecordAction >= POST_TIMER_RECORD_CLOSE) { if (iPostRecordAction >= POST_TIMER_RECORD_CLOSE) {
do { do {
// Set the flags as appropriate based on what we have done
wxUint32 eActionFlags = TR_ACTION_NOTHING;
if (m_bAutoSaveEnabled && bSaveOK) {
eActionFlags |= TR_ACTION_SAVED;
}
if (m_bAutoExportEnabled && bExportOK) {
eActionFlags |= TR_ACTION_EXPORTED;
}
// Lets show a warning dialog telling the user what is about to happen. // Lets show a warning dialog telling the user what is about to happen.
// If the user no longer wants to carry out this action then they can click // If the user no longer wants to carry out this action then they can click
// Cancel and we will do POST_TIMER_RECORD_NOTHING instead. // Cancel and we will do POST_TIMER_RECORD_NOTHING instead.
int iDelayOutcome = PreActionDelay(iPostRecordAction, (m_bAutoSaveEnabled && bSaveOK), int iDelayOutcome = PreActionDelay(iPostRecordAction, (TimerRecordCompletedActions)eActionFlags);
(m_bAutoExportEnabled && bExportOK));
if (iDelayOutcome != eProgressSuccess) { if (iDelayOutcome != eProgressSuccess) {
// Cancel the action! // Cancel the action!
iPostRecordAction = POST_TIMER_RECORD_NOTHING; iPostRecordAction = POST_TIMER_RECORD_NOTHING;
@ -912,18 +957,32 @@ void TimerRecordDialog::UpdateEnd()
int TimerRecordDialog::WaitForStart() int TimerRecordDialog::WaitForStart()
{ {
wxString strMsg; // MY: The Waiting For Start dialog now shows what actions will occur after recording has completed
/* i18n-hint: A time specification like "Sunday 28th October 2007 15:16:17 GMT" wxString sPostAction = m_pTimerAfterCompleteChoiceCtrl->GetString(m_pTimerAfterCompleteChoiceCtrl->GetSelection());
/* i18n-hint: Time specifications like "Sunday 28th October 2007 15:16:17 GMT"
* but hopefully translated by wxwidgets will be inserted into this */ * but hopefully translated by wxwidgets will be inserted into this */
strMsg.Printf(_("Waiting to start recording at %s.\n"), wxString strMsg;
GetDisplayDate(m_DateTime_Start).c_str()); strMsg.Printf(_("Waiting to start recording at:\t%s\n") +
_("Recording duration:\t\t%s\n") +
_("Scheduled to stop at:\t\t%s\n\n") +
_("Automatic Save Enabled:\t\t%s\n") +
_("Automatic Export Enabled:\t\t%s\n") +
_("Post Timer Recording Action:\t%s"),
GetDisplayDate(m_DateTime_Start).c_str(),
m_TimeSpan_Duration.Format(),
GetDisplayDate(m_DateTime_End).c_str(),
(m_bAutoSaveEnabled ? _("Yes") : _("No")),
(m_bAutoExportEnabled ? _("Yes") : _("No")),
sPostAction);
wxDateTime startWait_DateTime = wxDateTime::UNow(); wxDateTime startWait_DateTime = wxDateTime::UNow();
wxTimeSpan waitDuration = m_DateTime_Start - startWait_DateTime; wxTimeSpan waitDuration = m_DateTime_Start - startWait_DateTime;
TimerProgressDialog TimerProgressDialog progress(waitDuration.GetMilliseconds().GetValue(),
progress(waitDuration.GetMilliseconds().GetValue(),
_("Audacity Timer Record - Waiting for Start"), _("Audacity Timer Record - Waiting for Start"),
strMsg, strMsg,
pdlgHideStopButton); pdlgHideStopButton | pdlgConfirmStopCancel | pdlgHideElapsedTime,
_("Recording will commence in:"));
int updateResult = eProgressSuccess; int updateResult = eProgressSuccess;
bool bIsRecording = false; bool bIsRecording = false;
@ -936,28 +995,21 @@ int TimerRecordDialog::WaitForStart()
return updateResult; return updateResult;
} }
// TODO: Rather than two flags, an enum with the possibilities would be better. int TimerRecordDialog::PreActionDelay(int iActionIndex, TimerRecordCompletedActions eCompletedActions)
int TimerRecordDialog::PreActionDelay(int iActionIndex, bool bSaved, bool bExported)
{ {
wxString sMessage;
wxString sAction = m_pTimerAfterCompleteChoiceCtrl->GetString(iActionIndex); wxString sAction = m_pTimerAfterCompleteChoiceCtrl->GetString(iActionIndex);
wxString sDone = ""; wxString sCountdownLabel;
if (bSaved && bExported) { sCountdownLabel.Printf("%s in:", sAction);
sDone = _("Saved and Exported");
} // Build a clearer message...
else if (bSaved) { wxString sMessage;
sDone = _("Saved"); sMessage.Printf(_("Timer Recording Completed.\n\n") +
} _("Recording Saved:\t\t\t%s\n") +
else if (bExported) { _("Recording Exported:\t\t%s\n") +
sDone = _("Exported"); _("Post Timer Recording Action:\t%s"),
} ((eCompletedActions & TR_ACTION_SAVED) ? _("Yes") : _("No")),
// TODO: The wording will sound better if there are complete messages for ((eCompletedActions & TR_ACTION_EXPORTED) ? _("Yes") : _("No")),
// the will-occur-shortly messages. sAction);
/* i18n-hint: The first %s will be a translation of 'Saved', 'Exported' or
* 'Saved and Exported'. The second %s will be 'Exit Audacity'
* 'Restart System' or 'Shutdown System' */
sMessage.Printf(_("Timer Recording completed: Recording has been %s.\n\n'%s' will occur shortly...\n"),
sDone, sAction);
wxDateTime dtNow = wxDateTime::UNow(); wxDateTime dtNow = wxDateTime::UNow();
wxTimeSpan tsWait = wxTimeSpan(0, 1, 0, 0); wxTimeSpan tsWait = wxTimeSpan(0, 1, 0, 0);
@ -966,7 +1018,8 @@ int TimerRecordDialog::PreActionDelay(int iActionIndex, bool bSaved, bool bExpor
TimerProgressDialog dlgAction(tsWait.GetMilliseconds().GetValue(), TimerProgressDialog dlgAction(tsWait.GetMilliseconds().GetValue(),
_("Audacity Timer Record - Waiting"), _("Audacity Timer Record - Waiting"),
sMessage, sMessage,
pdlgHideStopButton); pdlgHideStopButton | pdlgHideElapsedTime,
sCountdownLabel);
int iUpdateResult = eProgressSuccess; int iUpdateResult = eProgressSuccess;
bool bIsTime = false; bool bIsTime = false;

View File

@ -30,6 +30,12 @@ class NumericTextCtrl;
class ShuttleGui; class ShuttleGui;
class TimerRecordPathCtrl; class TimerRecordPathCtrl;
enum TimerRecordCompletedActions {
TR_ACTION_NOTHING = 0x00000000,
TR_ACTION_SAVED = 0x00000001,
TR_ACTION_EXPORTED = 0x00000002
};
class TimerRecordPathCtrl final : public wxTextCtrl class TimerRecordPathCtrl final : public wxTextCtrl
{ {
// MY: Class that inherits from the wxTextCtrl class. // MY: Class that inherits from the wxTextCtrl class.
@ -93,7 +99,7 @@ private:
int ExecutePostRecordActions(bool bWasStopped); int ExecutePostRecordActions(bool bWasStopped);
int PreActionDelay(int iActionIndex, bool bSaved, bool bExported); int PreActionDelay(int iActionIndex, TimerRecordCompletedActions eCompletedActions);
private: private:
wxDateTime m_DateTime_Start; wxDateTime m_DateTime_Start;

View File

@ -996,13 +996,14 @@ ProgressDialog::ProgressDialog()
} }
ProgressDialog::ProgressDialog(const wxString & title, ProgressDialog::ProgressDialog(const wxString & title,
const wxString & message, const wxString & message /* = wxEmptyString*/,
int flags) int flags /* = pdlgDefaultFlags */,
const wxString & sRemainingLabelText /* = wxEmptyString */)
: wxDialog() : wxDialog()
{ {
Init(); Init();
Create(title, message, flags); Create(title, message, flags, sRemainingLabelText);
} }
// //
@ -1070,11 +1071,17 @@ void ProgressDialog::Init()
} }
bool ProgressDialog::Create(const wxString & title, bool ProgressDialog::Create(const wxString & title,
const wxString & message, const wxString & message /* = wxEmptyString */,
int flags) int flags /* = pdlgDefaultFlags */,
const wxString & sRemainingLabelText /* = wxEmptyString */)
{ {
wxWindow *parent = GetParentForModalDialog(NULL, 0); wxWindow *parent = GetParentForModalDialog(NULL, 0);
// Set this boolean to indicate if we are using the "Elapsed" labels
m_bShowElapsedTime = !(flags & pdlgHideElapsedTime);
// Set this boolean to indicate if we confirm the Cancel/Stop actions
m_bConfirmAction = (flags & pdlgConfirmStopCancel);
bool success = wxDialog::Create(parent, bool success = wxDialog::Create(parent,
wxID_ANY, wxID_ANY,
title, title,
@ -1125,8 +1132,13 @@ bool ProgressDialog::Create(const wxString & title,
// //
{ {
auto ug = std::make_unique<wxFlexGridSizer>(2, 2, 10, 10); auto ug = std::make_unique<wxFlexGridSizer>(2, 2, 10, 10);
// MY: Only one row if we are not going to show the elapsed time
if (m_bShowElapsedTime == false) {
ug = std::make_unique<wxFlexGridSizer>(1, 2, 10, 10);
}
g = ug.get(); g = ug.get();
if (m_bShowElapsedTime) {
w = safenew wxStaticText(this, w = safenew wxStaticText(this,
wxID_ANY, wxID_ANY,
_("Elapsed Time:"), _("Elapsed Time:"),
@ -1145,13 +1157,20 @@ bool ProgressDialog::Create(const wxString & title,
mElapsed->SetName(mElapsed->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs) mElapsed->SetName(mElapsed->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
g->Add(mElapsed, 0, wxALIGN_LEFT); g->Add(mElapsed, 0, wxALIGN_LEFT);
ds.y += mElapsed->GetSize().y + 10; ds.y += mElapsed->GetSize().y + 10;
}
// Customised "Remaining" label text
wxString sRemainingText = sRemainingLabelText;
if (sRemainingText == wxEmptyString) {
sRemainingText = _("Remaining Time:");
}
// //
// //
// //
w = safenew wxStaticText(this, w = safenew wxStaticText(this,
wxID_ANY, wxID_ANY,
_("Remaining Time:"), sRemainingText,
wxDefaultPosition, wxDefaultPosition,
wxDefaultSize, wxDefaultSize,
wxALIGN_RIGHT); wxALIGN_RIGHT);
@ -1180,12 +1199,14 @@ bool ProgressDialog::Create(const wxString & title,
{ {
w = safenew wxButton(this, wxID_OK, _("Stop")); w = safenew wxButton(this, wxID_OK, _("Stop"));
h->Add(w, 0, wxRIGHT, 10); h->Add(w, 0, wxRIGHT, 10);
m_btnStop = w;
} }
if (!(flags & pdlgHideCancelButton)) if (!(flags & pdlgHideCancelButton))
{ {
w = safenew wxButton(this, wxID_CANCEL, _("Cancel")); w = safenew wxButton(this, wxID_CANCEL, _("Cancel"));
h->Add(w, 0, wxRIGHT, 10); h->Add(w, 0, wxRIGHT, 10);
m_btnCancel = w;
} }
v->Add(uh.release(), 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 10); v->Add(uh.release(), 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 10);
@ -1201,6 +1222,10 @@ bool ProgressDialog::Create(const wxString & title,
wxClientDC dc(this); wxClientDC dc(this);
dc.GetMultiLineTextExtent(message, &mLastW, &mLastH); dc.GetMultiLineTextExtent(message, &mLastW, &mLastH);
// MY: Add a little bit more width when we have TABs to stop words wrapping
int iTabFreq = wxMax((message.Freq('\t') - 1), 0);
mLastW = mLastW + (iTabFreq * 8);
#if defined(__WXMAC__) #if defined(__WXMAC__)
mMessage->SetMinSize(wxSize(mLastW, mLastH)); mMessage->SetMinSize(wxSize(mLastW, mLastH));
#endif #endif
@ -1297,12 +1322,14 @@ int ProgressDialog::Update(int value, const wxString & message)
// Only update if a full second has passed or track progress is complete // Only update if a full second has passed or track progress is complete
if ((now - mLastUpdate > 1000) || (value == 1000)) if ((now - mLastUpdate > 1000) || (value == 1000))
{ {
if (m_bShowElapsedTime) {
wxTimeSpan tsElapsed(0, 0, 0, elapsed); wxTimeSpan tsElapsed(0, 0, 0, elapsed);
wxTimeSpan tsRemains(0, 0, 0, remains);
mElapsed->SetLabel(tsElapsed.Format(wxT("%H:%M:%S"))); mElapsed->SetLabel(tsElapsed.Format(wxT("%H:%M:%S")));
mElapsed->SetName(mElapsed->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs) mElapsed->SetName(mElapsed->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
mElapsed->Update(); mElapsed->Update();
}
wxTimeSpan tsRemains(0, 0, 0, remains);
mRemaining->SetLabel(tsRemains.Format(wxT("%H:%M:%S"))); mRemaining->SetLabel(tsRemains.Format(wxT("%H:%M:%S")));
mRemaining->SetName(mRemaining->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs) mRemaining->SetName(mRemaining->GetLabel()); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
mRemaining->Update(); mRemaining->Update();
@ -1477,12 +1504,36 @@ bool ProgressDialog::SearchForWindow(const wxWindowList & list, const wxWindow *
void ProgressDialog::OnCancel(wxCommandEvent & WXUNUSED(event)) void ProgressDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
{ {
if (m_bConfirmAction) {
wxString sPrompt = _("Are you sure you wish to cancel?");
wxMessageDialog dlgMessage(this,
sPrompt,
_("Confirm Cancel"),
wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT | wxSTAY_ON_TOP);
int iAction = dlgMessage.ShowModal();
if (iAction != wxID_YES) {
m_btnCancel->SetFocus();
return;
}
}
FindWindowById(wxID_CANCEL, this)->Disable(); FindWindowById(wxID_CANCEL, this)->Disable();
mCancel = true; mCancel = true;
} }
void ProgressDialog::OnStop(wxCommandEvent & WXUNUSED(event)) void ProgressDialog::OnStop(wxCommandEvent & WXUNUSED(event))
{ {
if (m_bConfirmAction) {
wxString sPrompt = _("Are you sure you wish to stop?");
wxMessageDialog dlgMessage(this,
sPrompt,
_("Confirm Stop"),
wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT | wxSTAY_ON_TOP);
int iAction = dlgMessage.ShowModal();
if (iAction != wxID_YES) {
m_btnStop->SetFocus();
return;
}
}
FindWindowById(wxID_OK, this)->Disable(); FindWindowById(wxID_OK, this)->Disable();
mCancel = false; mCancel = false;
mStop = true; mStop = true;
@ -1490,6 +1541,17 @@ void ProgressDialog::OnStop(wxCommandEvent & WXUNUSED(event))
void ProgressDialog::OnCloseWindow(wxCloseEvent & WXUNUSED(event)) void ProgressDialog::OnCloseWindow(wxCloseEvent & WXUNUSED(event))
{ {
if (m_bConfirmAction) {
wxString sPrompt = _("Are you sure you wish to close?");
wxMessageDialog dlgMessage(this,
sPrompt,
_("Confirm Close"),
wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT | wxSTAY_ON_TOP);
int iAction = dlgMessage.ShowModal();
if (iAction != wxID_YES) {
return;
}
}
mCancel = true; mCancel = true;
} }
@ -1526,9 +1588,10 @@ void ProgressDialog::Beep() const
TimerProgressDialog::TimerProgressDialog(const wxLongLong_t duration, TimerProgressDialog::TimerProgressDialog(const wxLongLong_t duration,
const wxString & title, const wxString & title,
const wxString & message /*= wxEmptyString*/, const wxString & message /* = wxEmptyString */,
int flags /*= pdlgEmptyFlags*/) int flags /* = pdlgDefaultFlags */,
: ProgressDialog(title, message, flags) const wxString & sRemainingLabelText /* = wxEmptyString */)
: ProgressDialog(title, message, flags, sRemainingLabelText)
{ {
mDuration = duration; mDuration = duration;
} }
@ -1587,11 +1650,13 @@ int TimerProgressDialog::Update(const wxString & message /*= wxEmptyString*/)
// Only update if a full second has passed. // Only update if a full second has passed.
if (now - mLastUpdate > 1000) if (now - mLastUpdate > 1000)
{ {
if (m_bShowElapsedTime) {
wxTimeSpan tsElapsed(0, 0, 0, elapsed); wxTimeSpan tsElapsed(0, 0, 0, elapsed);
wxTimeSpan tsRemains(0, 0, 0, remains);
mElapsed->SetLabel(tsElapsed.Format(wxT("%H:%M:%S"))); mElapsed->SetLabel(tsElapsed.Format(wxT("%H:%M:%S")));
mElapsed->Update(); mElapsed->Update();
}
wxTimeSpan tsRemains(0, 0, 0, remains);
mRemaining->SetLabel(tsRemains.Format(wxT("%H:%M:%S"))); mRemaining->SetLabel(tsRemains.Format(wxT("%H:%M:%S")));
mRemaining->Update(); mRemaining->Update();

View File

@ -26,6 +26,7 @@
#include <wx/gauge.h> #include <wx/gauge.h>
#include <wx/stattext.h> #include <wx/stattext.h>
#include <wx/utils.h> #include <wx/utils.h>
#include <wx/msgdlg.h>
enum enum
{ {
@ -40,6 +41,8 @@ enum ProgressDialogFlags
pdlgEmptyFlags = 0x00000000, pdlgEmptyFlags = 0x00000000,
pdlgHideStopButton = 0x00000001, pdlgHideStopButton = 0x00000001,
pdlgHideCancelButton = 0x00000002, pdlgHideCancelButton = 0x00000002,
pdlgHideElapsedTime = 0x00000004,
pdlgConfirmStopCancel = 0x00000008,
pdlgDefaultFlags = pdlgEmptyFlags pdlgDefaultFlags = pdlgEmptyFlags
}; };
@ -52,11 +55,17 @@ class AUDACITY_DLL_API ProgressDialog /* not final */ : public wxDialog
{ {
public: public:
ProgressDialog(); ProgressDialog();
ProgressDialog(const wxString & title, const wxString & message = wxEmptyString, int flags = pdlgDefaultFlags); ProgressDialog(const wxString & title,
const wxString & message = wxEmptyString,
int flags = pdlgDefaultFlags,
const wxString & sRemainingLabelText = wxEmptyString);
virtual ~ProgressDialog(); virtual ~ProgressDialog();
// NEW virtual? It doesn't override wxDialog // NEW virtual? It doesn't override wxDialog
virtual bool Create(const wxString & title, const wxString & message = wxEmptyString, int flags = pdlgDefaultFlags); virtual bool Create(const wxString & title,
const wxString & message = wxEmptyString,
int flags = pdlgDefaultFlags,
const wxString & sRemainingLabelText = wxEmptyString);
int Update(int value, const wxString & message = wxEmptyString); int Update(int value, const wxString & message = wxEmptyString);
int Update(double current, const wxString & message = wxEmptyString); int Update(double current, const wxString & message = wxEmptyString);
@ -83,6 +92,14 @@ protected:
bool mIsTransparent; bool mIsTransparent;
// MY: Booleans to hold the flag values
bool m_bShowElapsedTime = true;
bool m_bConfirmAction = false;
// MY: Declare the buttons so we can se the focus on them later
wxWindow *m_btnStop;
wxWindow *m_btnCancel;
private: private:
void Init(); void Init();
bool SearchForWindow(const wxWindowList & list, const wxWindow *searchfor) const; bool SearchForWindow(const wxWindowList & list, const wxWindow *searchfor) const;
@ -110,7 +127,8 @@ public:
TimerProgressDialog(const wxLongLong_t duration, TimerProgressDialog(const wxLongLong_t duration,
const wxString & title, const wxString & title,
const wxString & message = wxEmptyString, const wxString & message = wxEmptyString,
int flags = pdlgDefaultFlags); int flags = pdlgDefaultFlags,
const wxString & sRemainingLabelText = wxEmptyString);
int Update(const wxString & message = wxEmptyString); int Update(const wxString & message = wxEmptyString);
protected: protected: