Audacity 3.2.0
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
TimerRecordDialog Class Referencefinal

Dialog for Timer Record, i.e., timed or long recording. More...

#include <TimerRecordDialog.h>

Inheritance diagram for TimerRecordDialog:
[legend]
Collaboration diagram for TimerRecordDialog:
[legend]

Public Types

using ProgressResult = BasicUI::ProgressResult
 

Public Member Functions

 TimerRecordDialog (wxWindow *parent, AudacityProject &project, bool bAlreadySaved)
 
 ~TimerRecordDialog ()
 
void OnTimer (wxTimerEvent &event)
 
int RunWaitDialog ()
 Runs the wait for start dialog. Returns false if the user clicks stop. More...
 
- Public Member Functions inherited from wxDialogWrapper
 wxDialogWrapper ()
 
 wxDialogWrapper (wxWindow *parent, wxWindowID id, const TranslatableString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE, const TranslatableString &name=XO("Dialog"))
 
bool Create (wxWindow *parent, wxWindowID id, const TranslatableString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE, const TranslatableString &name=XO("Dialog"))
 
void SetTitle (const TranslatableString &title)
 
void SetLabel (const TranslatableString &title)
 
void SetName (const TranslatableString &title)
 
void SetName ()
 
- Public Member Functions inherited from wxTabTraversalWrapper< wxDialog >
 wxTabTraversalWrapper (Args &&... args)
 
 wxTabTraversalWrapper (const wxTabTraversalWrapper &)=delete
 
 wxTabTraversalWrapper (wxTabTraversalWrapper &&)=delete
 
wxTabTraversalWrapperoperator= (const wxTabTraversalWrapper &)=delete
 
wxTabTraversalWrapperoperator= (wxTabTraversalWrapper &&)=delete
 

Private Member Functions

void OnDatePicker_Start (wxDateEvent &event)
 
void OnTimeText_Start (wxCommandEvent &event)
 
void OnDatePicker_End (wxDateEvent &event)
 
void OnTimeText_End (wxCommandEvent &event)
 
void OnTimeText_Duration (wxCommandEvent &event)
 
void OnOK (wxCommandEvent &event)
 
void OnHelpButtonClick (wxCommandEvent &event)
 
TranslatableString GetDisplayDate (wxDateTime &dt)
 
void PopulateOrExchange (ShuttleGui &S)
 
bool TransferDataFromWindow () override
 
void UpdateDuration ()
 
void UpdateEnd ()
 
ProgressResult WaitForStart ()
 
void OnAutoSavePathButton_Click (wxCommandEvent &event)
 
void OnAutoExportPathButton_Click (wxCommandEvent &event)
 
void OnAutoSaveCheckBox_Change (wxCommandEvent &event)
 
void OnAutoExportCheckBox_Change (wxCommandEvent &event)
 
void EnableDisableAutoControls (bool bEnable, int iControlGoup)
 
void UpdateTextBoxControls ()
 
wxTextCtrlWrapperNewPathControl (wxWindow *wParent, const int iID, const TranslatableString &sCaption, const TranslatableString &sValue)
 
int ExecutePostRecordActions (bool bWasStopped)
 
ProgressResult PreActionDelay (int iActionIndex, TimerRecordCompletedActions eCompletedActions)
 

Private Attributes

AudacityProjectmProject
 
wxDateTime m_DateTime_Start
 
wxDateTime m_DateTime_End
 
wxTimeSpan m_TimeSpan_Duration
 
wxDatePickerCtrl * m_pDatePickerCtrl_Start
 
NumericTextCtrlm_pTimeTextCtrl_Start
 
wxDatePickerCtrl * m_pDatePickerCtrl_End
 
NumericTextCtrlm_pTimeTextCtrl_End
 
NumericTextCtrlm_pTimeTextCtrl_Duration
 
wxTimer m_timer
 
wxCheckBox * m_pTimerAutoSaveCheckBoxCtrl
 
wxTextCtrlWrapperm_pTimerSavePathTextCtrl
 
wxButton * m_pTimerSavePathButtonCtrl
 
wxCheckBox * m_pTimerAutoExportCheckBoxCtrl
 
wxTextCtrlWrapperm_pTimerExportPathTextCtrl
 
wxButton * m_pTimerExportPathButtonCtrl
 
wxChoice * m_pTimerAfterCompleteChoiceCtrl
 
bool m_bProjectCleanupRequired
 
bool m_bAutoSaveEnabled
 
wxFileName m_fnAutoSaveFile
 
bool m_bAutoExportEnabled
 
wxFileName m_fnAutoExportFile
 
int m_iAutoExportFormat
 
int m_iAutoExportSubFormat
 
int m_iAutoExportFilterIndex
 
bool m_bProjectAlreadySaved
 

Detailed Description

Dialog for Timer Record, i.e., timed or long recording.

Definition at line 55 of file TimerRecordDialog.h.

Member Typedef Documentation

◆ ProgressResult

Definition at line 58 of file TimerRecordDialog.h.

Constructor & Destructor Documentation

◆ TimerRecordDialog()

TimerRecordDialog::TimerRecordDialog ( wxWindow *  parent,
AudacityProject project,
bool  bAlreadySaved 
)

Definition at line 153 of file TimerRecordDialog.cpp.

155: wxDialogWrapper(parent, -1, XO("Audacity Timer Record"), wxDefaultPosition,
156 wxDefaultSize, wxCAPTION)
157, mProject{ project }
158{
159 SetName();
160
161 m_DateTime_Start = wxDateTime::UNow();
162 long seconds; // default duration is 1 hour = 3600 seconds
163 gPrefs->Read(wxT("/TimerRecord/LastDuration"), &seconds, 3600);
164 m_TimeSpan_Duration = wxTimeSpan::Seconds(seconds);
166
169
171 m_pTimeTextCtrl_End = NULL;
172
174
175 // Do we allow the user to change the Automatic Save file?
176 m_bProjectAlreadySaved = bAlreadySaved;
177
178 ShuttleGui S(this, eIsCreating);
179 this->PopulateOrExchange(S);
180
181 // Set initial focus to "1" of "01h" in Duration NumericTextCtrl,
182 // instead of OK button (default).
183 m_pTimeTextCtrl_Duration->SetFocus();
185
186 m_timer.SetOwner(this, TIMER_ID);
188}
wxT("CloseDown"))
XO("Cut/Copy/Paste")
FileConfig * gPrefs
Definition: Prefs.cpp:70
@ eIsCreating
Definition: ShuttleGui.h:39
const int kSlowTimerInterval
#define TIMER_ID
#define S(N)
Definition: ToChars.cpp:64
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:628
wxDatePickerCtrl * m_pDatePickerCtrl_Start
NumericTextCtrl * m_pTimeTextCtrl_Duration
NumericTextCtrl * m_pTimeTextCtrl_End
AudacityProject & mProject
void PopulateOrExchange(ShuttleGui &S)
NumericTextCtrl * m_pTimeTextCtrl_Start
wxDateTime m_DateTime_Start
wxTimeSpan m_TimeSpan_Duration
wxDatePickerCtrl * m_pDatePickerCtrl_End

◆ ~TimerRecordDialog()

TimerRecordDialog::~TimerRecordDialog ( )

Definition at line 190 of file TimerRecordDialog.cpp.

191{
192}

Member Function Documentation

◆ EnableDisableAutoControls()

void TimerRecordDialog::EnableDisableAutoControls ( bool  bEnable,
int  iControlGoup 
)
private

Definition at line 448 of file TimerRecordDialog.cpp.

448 {
449
450 if (iControlGoup == CONTROL_GROUP_EXPORT) {
451 m_pTimerExportPathTextCtrl->Enable( bEnable );
452 m_pTimerExportPathButtonCtrl->Enable( bEnable);
453 } else if (iControlGoup == CONTROL_GROUP_SAVE) {
454 m_pTimerSavePathTextCtrl->Enable( bEnable);
455 m_pTimerSavePathButtonCtrl->Enable(bEnable );
456 }
457
458 // Enable or disable the Choice box - if there is no Save or Export then this will be disabled
459 if (m_pTimerAutoSaveCheckBoxCtrl->GetValue() || m_pTimerAutoExportCheckBoxCtrl->GetValue()) {
461 } else {
464 }
465}
@ CONTROL_GROUP_SAVE
@ CONTROL_GROUP_EXPORT
@ POST_TIMER_RECORD_NOTHING
wxButton * m_pTimerSavePathButtonCtrl
wxCheckBox * m_pTimerAutoSaveCheckBoxCtrl
wxTextCtrlWrapper * m_pTimerExportPathTextCtrl
wxChoice * m_pTimerAfterCompleteChoiceCtrl
wxCheckBox * m_pTimerAutoExportCheckBoxCtrl
wxTextCtrlWrapper * m_pTimerSavePathTextCtrl
wxButton * m_pTimerExportPathButtonCtrl

References CONTROL_GROUP_EXPORT, CONTROL_GROUP_SAVE, m_pTimerAfterCompleteChoiceCtrl, m_pTimerAutoExportCheckBoxCtrl, m_pTimerAutoSaveCheckBoxCtrl, m_pTimerExportPathButtonCtrl, m_pTimerExportPathTextCtrl, m_pTimerSavePathButtonCtrl, m_pTimerSavePathTextCtrl, and POST_TIMER_RECORD_NOTHING.

Referenced by OnAutoExportCheckBox_Change(), OnAutoSaveCheckBox_Change(), and PopulateOrExchange().

Here is the caller graph for this function:

◆ ExecutePostRecordActions()

int TimerRecordDialog::ExecutePostRecordActions ( bool  bWasStopped)
private

Definition at line 557 of file TimerRecordDialog.cpp.

557 {
558 // MY: We no longer automatically (and silently) call ->Save() when the
559 // timer recording is completed. We can now Save and/or Export depending
560 // on the options selected by the user.
561 // Once completed, we can also close Audacity, restart the system or
562 // shutdown the system.
563 // If there was any error with the auto save or export then we will not do
564 // the actions requested and instead present an error mesasge to the user.
565 // Finally, if there is no post-record action selected then we output
566 // a dialog detailing what has been carried out instead.
567
568 bool bSaveOK = false;
569 bool bExportOK = false;
570 int iPostRecordAction = m_pTimerAfterCompleteChoiceCtrl->GetSelection();
571 int iOverriddenAction = iPostRecordAction;
572 bool bErrorOverride = false;
573
574 // Do Automatic Save?
575 if (m_bAutoSaveEnabled) {
576
577 auto &projectFileManager = ProjectFileManager::Get( mProject );
578 // MY: If this project has already been saved then simply execute a Save here
580 bSaveOK = projectFileManager.Save();
581 } else {
582 bSaveOK = projectFileManager.SaveFromTimerRecording(m_fnAutoSaveFile);
583 }
584 }
585
586 // Do Automatic Export?
588 Exporter e{ mProject };
589 bExportOK = e.ProcessFromTimerRecording(
590 false, 0.0, TrackList::Get( mProject ).GetEndTime(),
593 }
594
595 // Check if we need to override the post recording action
596 bErrorOverride = ((m_bAutoSaveEnabled && !bSaveOK) || (m_bAutoExportEnabled && !bExportOK));
597 if (bErrorOverride || bWasStopped) {
598 iPostRecordAction = POST_TIMER_RECORD_NOTHING;
599 }
600
601 if (iPostRecordAction == POST_TIMER_RECORD_NOTHING) {
602 // If there is no post-record action then we can show a message indicating what has been done
603
604 auto sMessage = (bWasStopped ? XO("Timer Recording stopped.") :
605 XO("Timer Recording completed."));
606
607 if (m_bAutoSaveEnabled) {
608 if (bSaveOK) {
609 sMessage = XO("%s\n\nRecording saved: %s").Format(
610 sMessage, m_fnAutoSaveFile.GetFullPath());
611 } else {
612 sMessage = XO("%s\n\nError saving recording.").Format( sMessage );
613 }
614 }
616 if (bExportOK) {
617 sMessage = XO("%s\n\nRecording exported: %s").Format(
618 sMessage, m_fnAutoExportFile.GetFullPath());
619 } else {
620 sMessage = XO("%s\n\nError exporting recording.").Format( sMessage );
621 }
622 }
623
624 if (bErrorOverride) {
625
626 if ((iOverriddenAction != iPostRecordAction) &&
627 (iOverriddenAction != POST_TIMER_RECORD_NOTHING)) {
628 // Inform the user that we have overridden the selected action
629 sMessage = XO("%s\n\n'%s' has been canceled due to the error(s) noted above.").Format(
630 sMessage,
631 m_pTimerAfterCompleteChoiceCtrl->GetString(iOverriddenAction));
632 }
633
634 // Show Error Message Box
636 sMessage,
637 XO("Error"),
638 wxICON_EXCLAMATION | wxOK);
639 } else {
640
641 if (bWasStopped && (iOverriddenAction != POST_TIMER_RECORD_NOTHING)) {
642 sMessage = XO("%s\n\n'%s' has been canceled as the recording was stopped.").Format(
643 sMessage,
644 m_pTimerAfterCompleteChoiceCtrl->GetString(iOverriddenAction));
645 }
646
648 sMessage,
649 XO("Timer Recording"),
650 wxICON_INFORMATION | wxOK);
651 }
652 }
653
654 // MY: Lets do some actions that only apply to Exit/Restart/Shutdown
655 if (iPostRecordAction >= POST_TIMER_RECORD_CLOSE) {
656 do {
657
658 // Set the flags as appropriate based on what we have done
659 wxUint32 eActionFlags = TR_ACTION_NOTHING;
660 if (m_bAutoSaveEnabled && bSaveOK) {
661 eActionFlags |= TR_ACTION_SAVED;
662 }
663 if (m_bAutoExportEnabled && bExportOK) {
664 eActionFlags |= TR_ACTION_EXPORTED;
665 }
666
667 // Lets show a warning dialog telling the user what is about to happen.
668 // If the user no longer wants to carry out this action then they can click
669 // Cancel and we will do POST_TIMER_RECORD_NOTHING instead.
670 auto iDelayOutcome = PreActionDelay(iPostRecordAction, (TimerRecordCompletedActions)eActionFlags);
671 if (iDelayOutcome != ProgressResult::Success) {
672 // Cancel the action!
673 iPostRecordAction = POST_TIMER_RECORD_NOTHING;
674 break;
675 }
676 } while (false);
677 }
678
679 // Return the action as required
680 return iPostRecordAction;
681}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
@ POST_TIMER_RECORD_CLOSE
TimerRecordCompletedActions
@ TR_ACTION_NOTHING
@ TR_ACTION_EXPORTED
@ TR_ACTION_SAVED
static ProjectFileManager & Get(AudacityProject &project)
wxFileName m_fnAutoSaveFile
wxFileName m_fnAutoExportFile
ProgressResult PreActionDelay(int iActionIndex, TimerRecordCompletedActions eCompletedActions)
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:486

References AudacityMessageBox(), TrackList::Get(), ProjectFileManager::Get(), m_bAutoExportEnabled, m_bAutoSaveEnabled, m_bProjectAlreadySaved, m_fnAutoExportFile, m_fnAutoSaveFile, m_iAutoExportFilterIndex, m_iAutoExportFormat, m_iAutoExportSubFormat, m_pTimerAfterCompleteChoiceCtrl, mProject, POST_TIMER_RECORD_CLOSE, POST_TIMER_RECORD_NOTHING, PreActionDelay(), BasicUI::Success, TR_ACTION_EXPORTED, TR_ACTION_NOTHING, TR_ACTION_SAVED, and XO().

Referenced by RunWaitDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetDisplayDate()

TranslatableString TimerRecordDialog::GetDisplayDate ( wxDateTime &  dt)
private

Definition at line 683 of file TimerRecordDialog.cpp.

684{
685#if defined(__WXMSW__)
686 // On Windows, wxWidgets uses the system date control and it displays the
687 // date based on the Windows locale selected by the user. But, wxDateTime
688 // using the strftime function to return the formatted date. Since the
689 // default locale for the Windows CRT environment is "C", the dates come
690 // back in a different format.
691 //
692 // So, we make direct Windows calls to format the date like it the date
693 // control.
694 //
695 // (Most of this taken from src/msw/datectrl.cpp)
696
697 const wxDateTime::Tm tm(dt.GetTm());
698 SYSTEMTIME st;
699 wxString s;
700 int len;
701
702 st.wYear = (WXWORD)tm.year;
703 st.wMonth = (WXWORD)(tm.mon - wxDateTime::Jan + 1);
704 st.wDay = tm.mday;
705 st.wDayOfWeek = st.wMinute = st.wSecond = st.wMilliseconds = 0;
706
707 len = ::GetDateFormat(LOCALE_USER_DEFAULT,
708 DATE_SHORTDATE,
709 &st,
710 NULL,
711 NULL,
712 0);
713 if (len > 0) {
714 len = ::GetDateFormat(LOCALE_USER_DEFAULT,
715 DATE_SHORTDATE,
716 &st,
717 NULL,
718 wxStringBuffer(s, len),
719 len);
720 if (len > 0) {
721 s += wxT(" ") + dt.FormatTime();
722 return Verbatim( s );
723 }
724 }
725#endif
726
727 // Use default formatting
728wxPrintf(wxT("%s\n"), dt.Format());
729 return Verbatim( dt.FormatDate() + wxT(" ") + dt.FormatTime() );
730}
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.

References Verbatim(), and wxT().

Referenced by RunWaitDialog(), and WaitForStart().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ NewPathControl()

wxTextCtrlWrapper * TimerRecordDialog::NewPathControl ( wxWindow *  wParent,
const int  iID,
const TranslatableString sCaption,
const TranslatableString sValue 
)
private

Definition at line 732 of file TimerRecordDialog.cpp.

735{
736 wxTextCtrlWrapper * pTextCtrl;
737 wxASSERT(wParent); // to justify safenew
738 pTextCtrl = safenew wxTextCtrlWrapper(wParent, iID, sValue.Translation());
739 pTextCtrl->SetName(sCaption.Translation());
740 return pTextCtrl;
741}
#define safenew
Definition: MemoryX.h:10
wxString Translation() const

References safenew, and TranslatableString::Translation().

Referenced by PopulateOrExchange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnAutoExportCheckBox_Change()

void TimerRecordDialog::OnAutoExportCheckBox_Change ( wxCommandEvent &  event)
private

Definition at line 360 of file TimerRecordDialog.cpp.

360 {
362}
void EnableDisableAutoControls(bool bEnable, int iControlGoup)

References CONTROL_GROUP_EXPORT, EnableDisableAutoControls(), and m_pTimerAutoExportCheckBoxCtrl.

Here is the call graph for this function:

◆ OnAutoExportPathButton_Click()

void TimerRecordDialog::OnAutoExportPathButton_Click ( wxCommandEvent &  event)
private

Definition at line 339 of file TimerRecordDialog.cpp.

340{
341 Exporter eExporter{ mProject };
342
343 // Call the Exporter to set the options required
344 if (eExporter.SetAutoExportOptions()) {
345 // Populate the options so that we can destroy this instance of the Exporter
346 m_fnAutoExportFile = eExporter.GetAutoExportFileName();
347 m_iAutoExportFormat = eExporter.GetAutoExportFormat();
348 m_iAutoExportSubFormat = eExporter.GetAutoExportSubFormat();
349 m_iAutoExportFilterIndex = eExporter.GetAutoExportFilterIndex();
350
351 // Update the text controls
352 this->UpdateTextBoxControls();
353 }
354}

References m_fnAutoExportFile, m_iAutoExportFilterIndex, m_iAutoExportFormat, m_iAutoExportSubFormat, mProject, and UpdateTextBoxControls().

Here is the call graph for this function:

◆ OnAutoSaveCheckBox_Change()

void TimerRecordDialog::OnAutoSaveCheckBox_Change ( wxCommandEvent &  event)
private

Definition at line 356 of file TimerRecordDialog.cpp.

References CONTROL_GROUP_SAVE, EnableDisableAutoControls(), and m_pTimerAutoSaveCheckBoxCtrl.

Here is the call graph for this function:

◆ OnAutoSavePathButton_Click()

void TimerRecordDialog::OnAutoSavePathButton_Click ( wxCommandEvent &  event)
private

Definition at line 301 of file TimerRecordDialog.cpp.

302{
303 auto &projectFileIO = ProjectFileIO::Get(mProject);
304
305 wxString fName = SelectFile(FileNames::Operation::Export,
306 XO("Save Timer Recording As"),
307 m_fnAutoSaveFile.GetPath(),
308 m_fnAutoSaveFile.GetFullName(),
309 wxT("aup3"),
311 wxFD_SAVE | wxRESIZE_BORDER,
312 this);
313
314 if (fName.empty())
315 return;
316
317 // If project already exists then abort - we do not allow users to overwrite an existing project
318 // unless it is the current project.
319 if (wxFileExists(fName) && (projectFileIO.GetFileName() != fName)) {
321 nullptr,
322 XO("The selected file name could not be used\nfor Timer Recording because it \
323would overwrite another project.\nPlease try again and select an original name."),
324 XO("Error Saving Timer Recording Project"),
325 wxOK|wxICON_ERROR );
326 m.ShowModal();
327 return;
328 }
329
330 // Set this boolean to false so we now do a SaveAs at the end of the recording
331 // unless we're saving the current project.
332 m_bProjectAlreadySaved = projectFileIO.GetFileName() == fName? true : false;
333
334 m_fnAutoSaveFile = fName;
335 m_fnAutoSaveFile.SetExt(wxT("aup3"));
336 this->UpdateTextBoxControls();
337}
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)
Definition: SelectFile.cpp:17
Wrap wxMessageDialog so that caption IS translatable.
FILES_API const FileType AudacityProjects
Definition: FileNames.h:71
static ProjectFileIO & Get(AudacityProject &project)

References FileNames::AudacityProjects, ProjectFileIO::Get(), m_bProjectAlreadySaved, m_fnAutoSaveFile, mProject, SelectFile(), UpdateTextBoxControls(), wxT(), and XO().

Here is the call graph for this function:

◆ OnDatePicker_End()

void TimerRecordDialog::OnDatePicker_End ( wxDateEvent &  event)
private

Definition at line 247 of file TimerRecordDialog.cpp.

248{
250 double dTime = m_pTimeTextCtrl_End->GetValue();
251 long hr = (long)(dTime / 3600.0);
252 long min = (long)((dTime - (hr * 3600.0)) / 60.0);
253 long sec = (long)(dTime - (hr * 3600.0) - (min * 60.0));
254 m_DateTime_End.SetHour(hr);
255 m_DateTime_End.SetMinute(min);
256 m_DateTime_End.SetSecond(sec);
257
258 // DatePickerCtrls use SetRange to make sure End is never less than Start, but
259 // need to implement it for the TimeTextCtrls.
264 }
265
266 this->UpdateDuration(); // Keep Start constant and update Duration for changed End.
267}
int min(int a, int b)
static double wxDateTime_to_AudacityTime(wxDateTime &dateTime)
void SetValue(double newValue)

References NumericConverter::GetValue(), m_DateTime_End, m_DateTime_Start, m_pDatePickerCtrl_End, m_pTimeTextCtrl_End, min(), NumericTextCtrl::SetValue(), UpdateDuration(), and wxDateTime_to_AudacityTime().

Referenced by OnTimeText_End().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnDatePicker_Start()

void TimerRecordDialog::OnDatePicker_Start ( wxDateEvent &  event)
private

Definition at line 205 of file TimerRecordDialog.cpp.

206{
208 double dTime = m_pTimeTextCtrl_Start->GetValue();
209 long hr = (long)(dTime / 3600.0);
210 long min = (long)((dTime - (hr * 3600.0)) / 60.0);
211 long sec = (long)(dTime - (hr * 3600.0) - (min * 60.0));
212 m_DateTime_Start.SetHour(hr);
213 m_DateTime_Start.SetMinute(min);
214 m_DateTime_Start.SetSecond(sec);
215
216 // User might have had the dialog up for a while, or
217 // had a future day, set hour of day less than now's, then changed day to today.
218 wxTimerEvent dummyTimerEvent;
219 this->OnTimer(dummyTimerEvent);
220
221 // Always update End for changed Start, keeping Duration constant.
222 // Note that OnTimer sometimes calls UpdateEnd, so sometimes this is redundant,
223 // but OnTimer doesn't need to always call UpdateEnd, but we must here.
224 this->UpdateEnd();
225}
void OnTimer(wxTimerEvent &event)

References NumericConverter::GetValue(), m_DateTime_Start, m_pDatePickerCtrl_Start, m_pTimeTextCtrl_Start, min(), OnTimer(), and UpdateEnd().

Referenced by OnTimeText_Start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnHelpButtonClick()

void TimerRecordDialog::OnHelpButtonClick ( wxCommandEvent &  event)
private

Definition at line 364 of file TimerRecordDialog.cpp.

365{
366 HelpSystem::ShowHelp(this, L"Timer_Record", true);
367}
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:234

References HelpSystem::ShowHelp().

Here is the call graph for this function:

◆ OnOK()

void TimerRecordDialog::OnOK ( wxCommandEvent &  event)
private

Definition at line 369 of file TimerRecordDialog.cpp.

370{
372 if (!m_TimeSpan_Duration.IsPositive())
373 {
375 XO("Duration is zero. Nothing will be recorded."),
376 XO("Error in Duration"),
377 wxICON_EXCLAMATION | wxOK);
378 return;
379 }
380
381 // Validate that we have a Save and/or Export path setup if the appropriate check box is ticked
382 wxString sTemp = m_fnAutoSaveFile.GetFullPath();
383 if (m_pTimerAutoSaveCheckBoxCtrl->IsChecked()) {
384 if (!m_fnAutoSaveFile.IsOk() || m_fnAutoSaveFile.IsDir()) {
386 XO("Automatic Save path is invalid."),
387 XO("Error in Automatic Save"),
388 wxICON_EXCLAMATION | wxOK);
389 return;
390 }
391 }
392 if (m_pTimerAutoExportCheckBoxCtrl->IsChecked()) {
393 if (!m_fnAutoExportFile.IsOk() || m_fnAutoExportFile.IsDir()) {
395 XO("Automatic Export path is invalid."),
396 XO("Error in Automatic Export"),
397 wxICON_EXCLAMATION | wxOK);
398 return;
399 }
400 }
401
402 // MY: Estimate here if we have enough disk space to
403 // complete this Timer Recording.
404 // If we don't think there is enough space then ask the user
405 // if they want to continue.
406 // We don't stop the user from starting the recording
407 // as its possible that they plan to free up some
408 // space before the recording begins
409 auto &projectManager = ProjectManager::Get( mProject );
410
411 // How many minutes do we have left on the disc?
412 int iMinsLeft = projectManager.GetEstimatedRecordingMinsLeftOnDisk();
413
414 // How many minutes will this recording require?
415 int iMinsRecording = m_TimeSpan_Duration.GetMinutes();
416
417 // Do we have enough space?
418 if (iMinsRecording >= iMinsLeft) {
419
420 // Format the strings
421 auto sRemainingTime = projectManager.GetHoursMinsString(iMinsLeft);
422 auto sPlannedTime = projectManager.GetHoursMinsString(iMinsRecording);
423
424 // Create the message string
425 auto sMessage = XO(
426"You may not have enough free disk space to complete this Timer Recording, based on your current settings.\n\nDo you wish to continue?\n\nPlanned recording duration: %s\nRecording time remaining on disk: %s")
427 .Format( sPlannedTime, sRemainingTime );
428
429 AudacityMessageDialog dlgMessage(
430 nullptr,
431 sMessage,
432 XO("Timer Recording Disk Space Warning"),
433 wxYES_NO | wxNO_DEFAULT | wxICON_WARNING);
434 if (dlgMessage.ShowModal() != wxID_YES ) {
435 // User decided not to continue - bail out!
436 return;
437 }
438 }
439
440 m_timer.Stop(); // Don't need to keep updating m_DateTime_Start to prevent backdating.
441 this->EndModal(wxID_OK);
442 wxLongLong duration = m_TimeSpan_Duration.GetSeconds();
443 // this will assert if the duration won't fit in a long
444 gPrefs->Write(wxT("/TimerRecord/LastDuration"), duration.ToLong());
445 gPrefs->Flush();
446}
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
static ProjectManager & Get(AudacityProject &project)
bool TransferDataFromWindow() override

References AudacityMessageBox(), FileConfig::Flush(), ProjectManager::Get(), gPrefs, m_fnAutoExportFile, m_fnAutoSaveFile, m_pTimerAutoExportCheckBoxCtrl, m_pTimerAutoSaveCheckBoxCtrl, m_timer, m_TimeSpan_Duration, mProject, TransferDataFromWindow(), wxT(), and XO().

Here is the call graph for this function:

◆ OnTimer()

void TimerRecordDialog::OnTimer ( wxTimerEvent &  event)

Definition at line 194 of file TimerRecordDialog.cpp.

195{
196 wxDateTime dateTime_UNow = wxDateTime::UNow();
197 if (m_DateTime_Start < dateTime_UNow) {
198 m_DateTime_Start = dateTime_UNow;
201 this->UpdateEnd(); // Keep Duration constant and update End for changed Start.
202 }
203}

References m_DateTime_Start, m_pDatePickerCtrl_Start, m_pTimeTextCtrl_Start, NumericTextCtrl::SetValue(), UpdateEnd(), and wxDateTime_to_AudacityTime().

Referenced by OnDatePicker_Start(), and RunWaitDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnTimeText_Duration()

void TimerRecordDialog::OnTimeText_Duration ( wxCommandEvent &  event)
private

Definition at line 289 of file TimerRecordDialog.cpp.

290{
291 double dTime = m_pTimeTextCtrl_Duration->GetValue();
292 long hr = (long)(dTime / 3600.0);
293 long min = (long)((dTime - (hr * 3600.0)) / 60.0);
294 long sec = (long)(dTime - (hr * 3600.0) - (min * 60.0));
295 m_TimeSpan_Duration = wxTimeSpan(hr, min, sec); //v milliseconds?
296
297 this->UpdateEnd(); // Keep Start constant and update End for changed Duration.
298}

References NumericConverter::GetValue(), m_pTimeTextCtrl_Duration, m_TimeSpan_Duration, min(), and UpdateEnd().

Here is the call graph for this function:

◆ OnTimeText_End()

void TimerRecordDialog::OnTimeText_End ( wxCommandEvent &  event)
private

Definition at line 269 of file TimerRecordDialog.cpp.

270{
271 //v NumericTextCtrl doesn't implement upper ranges, i.e.,
272 // if I tell it "024 h 060 m 060 s", then
273 // user increments the hours past 23, it rolls over to 0
274 // (although if you increment below 0, it stays at 0).
275 // So instead, set the max to 99 and just catch hours > 24 and fix the ctrls.
276 double dTime = m_pTimeTextCtrl_End->GetValue();
277 long days = (long)(dTime / (24.0 * 3600.0));
278 if (days > 0) {
279 dTime -= (double)days * 24.0 * 3600.0;
280 m_DateTime_End += wxTimeSpan::Days(days);
283 }
284
285 wxDateEvent dummyDateEvent;
286 this->OnDatePicker_End(dummyDateEvent);
287}
void OnDatePicker_End(wxDateEvent &event)

References NumericConverter::GetValue(), m_DateTime_End, m_pDatePickerCtrl_End, m_pTimeTextCtrl_End, OnDatePicker_End(), and NumericTextCtrl::SetValue().

Here is the call graph for this function:

◆ OnTimeText_Start()

void TimerRecordDialog::OnTimeText_Start ( wxCommandEvent &  event)
private

Definition at line 227 of file TimerRecordDialog.cpp.

228{
229 //v NumericTextCtrl doesn't implement upper ranges, i.e.,
230 // if I tell it "024 h 060 m 060 s", then
231 // user increments the hours past 23, it rolls over to 0
232 // (although if you increment below 0, it stays at 0).
233 // So instead, set the max to 99 and just catch hours > 24 and fix the ctrls.
234 double dTime = m_pTimeTextCtrl_Start->GetValue();
235 long days = (long)(dTime / (24.0 * 3600.0));
236 if (days > 0) {
237 dTime -= (double)days * 24.0 * 3600.0;
238 m_DateTime_Start += wxTimeSpan::Days(days);
241 }
242
243 wxDateEvent dummyDateEvent;
244 this->OnDatePicker_Start(dummyDateEvent);
245}
void OnDatePicker_Start(wxDateEvent &event)

References NumericConverter::GetValue(), m_DateTime_Start, m_pDatePickerCtrl_Start, m_pTimeTextCtrl_Start, OnDatePicker_Start(), and NumericTextCtrl::SetValue().

Here is the call graph for this function:

◆ PopulateOrExchange()

void TimerRecordDialog::PopulateOrExchange ( ShuttleGui S)
private

Definition at line 743 of file TimerRecordDialog.cpp.

744{
745 bool bAutoSave = gPrefs->ReadBool("/TimerRecord/AutoSave", false);
746 bool bAutoExport = gPrefs->ReadBool("/TimerRecord/AutoExport", false);
747 int iPostTimerRecordAction = gPrefs->ReadLong("/TimerRecord/PostAction", 0);
748
749 S.SetBorder(5);
751 /* i18n-hint a format string for hours, minutes, and seconds */
752 auto strFormat = XO("099 h 060 m 060 s");
753 /* i18n-hint a format string for days, hours, minutes, and seconds */
754 auto strFormat1 = XO("099 days 024 h 060 m 060 s");
755
756 S.StartMultiColumn(2, wxCENTER);
757 {
758 S.StartVerticalLay(true);
759 {
760 /* i18n-hint: This string is used to configure the controls for times when the recording is
761 * started and stopped. As such it is important that only the alphabetic parts of the string
762 * are translated, with the numbers left exactly as they are.
763 * The 'h' indicates the first number displayed is hours, the 'm' indicates the second number
764 * displayed is minutes, and the 's' indicates that the third number displayed is seconds.
765 */
766 S.StartStatic(XO("Start Date and Time"), true);
767 {
769 safenew wxDatePickerCtrl(S.GetParent(), // wxWindow *parent,
770 ID_DATEPICKER_START, // wxWindowID id,
771 m_DateTime_Start); // const wxDateTime& dt = wxDefaultDateTime,
772 // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDP_DEFAULT | wxDP_SHOWCENTURY, const wxValidator& validator = wxDefaultValidator, const wxString& name = "datectrl")
773 m_pDatePickerCtrl_Start->SetRange(wxDateTime::Today(), wxInvalidDateTime); // No backdating.
774#if wxUSE_ACCESSIBILITY
775 m_pDatePickerCtrl_Start->SetAccessible( safenew DatePickerCtrlAx(m_pDatePickerCtrl_Start));
776#endif
777 S.Name(XO("Start Date"))
778 .AddWindow(m_pDatePickerCtrl_Start);
779
782 {}, 0, 44100,
783 Options{}
784 .MenuEnabled(false)
785 .Format(strFormat)
787 S.Name(XO("Start Time"))
788 .AddWindow(m_pTimeTextCtrl_Start);
789 }
790 S.EndStatic();
791
792 S.StartStatic(XO("End Date and Time"), true);
793 {
795 safenew wxDatePickerCtrl(S.GetParent(), // wxWindow *parent,
796 ID_DATEPICKER_END, // wxWindowID id,
797 m_DateTime_End); // const wxDateTime& dt = wxDefaultDateTime,
798 // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
799 // long style = wxDP_DEFAULT | wxDP_SHOWCENTURY,
800 // const wxValidator& validator = wxDefaultValidator,
801 // const wxString& name = "datectrl")
802 m_pDatePickerCtrl_End->SetRange(m_DateTime_Start, wxInvalidDateTime); // No backdating.
803#if wxUSE_ACCESSIBILITY
804 m_pDatePickerCtrl_End->SetAccessible( safenew DatePickerCtrlAx(m_pDatePickerCtrl_End));
805#endif
806 S.Name(XO("End Date"))
807 .AddWindow(m_pDatePickerCtrl_End);
808
811 {}, 0, 44100,
812 Options{}
813 .MenuEnabled(false)
814 .Format(strFormat)
816 S.Name(XO("End Time"))
817 .AddWindow(m_pTimeTextCtrl_End);
818 }
819 S.EndStatic();
820
821 S.StartStatic(XO("Duration"), true);
822 {
825 {}, 0, 44100,
826 Options{}
827 .MenuEnabled(false)
828 .Format(strFormat1)
829 .Value(true, m_TimeSpan_Duration.GetSeconds().ToDouble()));
830 /* i18n-hint: This string is used to configure the controls which shows the recording
831 * duration. As such it is important that only the alphabetic parts of the string
832 * are translated, with the numbers left exactly as they are.
833 * The string 'days' indicates that the first number in the control will be the number of days,
834 * then the 'h' indicates the second number displayed is hours, the 'm' indicates the third
835 * number displayed is minutes, and the 's' indicates that the fourth number displayed is
836 * seconds.
837 */
838 S.Name(XO("Duration"))
839 .AddWindow(m_pTimeTextCtrl_Duration);
840 }
841 S.EndStatic();
842 }
843 S.EndVerticalLay();
844
845 S.StartVerticalLay(true);
846 {
847 S.StartStatic(XO("Automatic Save"), true);
848 {
849 // If checked, the project will be saved when the recording is completed
850 m_pTimerAutoSaveCheckBoxCtrl = S.Id(ID_AUTOSAVE_CHECKBOX).AddCheckBox(XXO("Enable &Automatic Save?"),
851 bAutoSave);
852 S.StartMultiColumn(3, wxEXPAND);
853 {
854 TranslatableString sInitialValue;
855 auto sSaveValue = ProjectFileIO::Get(mProject).GetFileName();
856 if (!sSaveValue.empty()) {
857 m_fnAutoSaveFile.Assign(sSaveValue);
858 sInitialValue = XO("Current Project");
859 }
860 S.AddPrompt(XXO("Save Project As:"));
862 S.GetParent(), ID_AUTOSAVEPATH_TEXT,
863 XO("Save Project As:"), sInitialValue);
865 S.AddWindow(m_pTimerSavePathTextCtrl);
866 m_pTimerSavePathButtonCtrl = S.Id(ID_AUTOSAVEPATH_BUTTON).AddButton(XXO("Select..."));
867 }
868 S.EndMultiColumn();
869 }
870 S.EndStatic();
871
872 S.StartStatic(XO("Automatic Export"), true);
873 {
874 m_pTimerAutoExportCheckBoxCtrl = S.Id(ID_AUTOEXPORT_CHECKBOX).AddCheckBox(XXO("Enable Automatic &Export?"), bAutoExport);
875 S.StartMultiColumn(3, wxEXPAND);
876 {
877 S.AddPrompt(XXO("Export Project As:"));
879 S.GetParent(), ID_AUTOEXPORTPATH_TEXT,
880 XO("Export Project As:"), {});
882 S.AddWindow(m_pTimerExportPathTextCtrl);
883 m_pTimerExportPathButtonCtrl = S.Id(ID_AUTOEXPORTPATH_BUTTON).AddButton(XXO("Select..."));
884 }
885 S.EndMultiColumn();
886 }
887 S.EndStatic();
888
889 S.StartStatic(XO("Options"), true);
890 {
891
892 S.StartMultiColumn(1, wxEXPAND);
893 {
894 S.SetStretchyCol( 0 );
895 m_pTimerAfterCompleteChoiceCtrl = S.AddChoice(XXO("After Recording completes:"),
896 {
897 XO("Do nothing") ,
898 XO("Exit Audacity") ,
899 #ifdef __WINDOWS__
900 XO("Restart system") ,
901 XO("Shutdown system") ,
902 #endif
903 },
904 iPostTimerRecordAction
905 );
906 }
907 S.EndMultiColumn();
908 }
909 S.EndStatic();
910
911 }
912 S.EndVerticalLay();
913 }
914 S.EndMultiColumn();
915
916 // MY: Added the help button here
917 S.AddStandardButtons(eOkButton | eCancelButton | eHelpButton);
918
919 Layout();
920 Fit();
921 SetMinSize(GetSize());
922 Center();
923
926}
XXO("&Cut/Copy/Paste Toolbar")
@ eOkButton
Definition: ShuttleGui.h:597
@ eCancelButton
Definition: ShuttleGui.h:598
@ eHelpButton
Definition: ShuttleGui.h:601
@ ID_AUTOEXPORTPATH_BUTTON
@ ID_AUTOSAVEPATH_TEXT
@ ID_DATEPICKER_START
@ ID_AUTOSAVEPATH_BUTTON
@ ID_AUTOSAVE_CHECKBOX
@ ID_AUTOEXPORTPATH_TEXT
@ ID_TIMETEXT_DURATION
@ ID_TIMETEXT_END
@ ID_DATEPICKER_END
@ ID_TIMETEXT_START
@ ID_AUTOEXPORT_CHECKBOX
const FilePath & GetFileName() const
wxTextCtrlWrapper * NewPathControl(wxWindow *wParent, const int iID, const TranslatableString &sCaption, const TranslatableString &sValue)
Holds a msgid for the translation catalog; may also bind format arguments.
void SetReadOnly(bool readonly=true)

References CONTROL_GROUP_EXPORT, CONTROL_GROUP_SAVE, eCancelButton, eHelpButton, EnableDisableAutoControls(), eOkButton, ProjectFileIO::Get(), ProjectFileIO::GetFileName(), gPrefs, ID_AUTOEXPORT_CHECKBOX, ID_AUTOEXPORTPATH_BUTTON, ID_AUTOEXPORTPATH_TEXT, ID_AUTOSAVE_CHECKBOX, ID_AUTOSAVEPATH_BUTTON, ID_AUTOSAVEPATH_TEXT, ID_DATEPICKER_END, ID_DATEPICKER_START, ID_TIMETEXT_DURATION, ID_TIMETEXT_END, ID_TIMETEXT_START, m_DateTime_End, m_DateTime_Start, m_fnAutoSaveFile, m_pDatePickerCtrl_End, m_pDatePickerCtrl_Start, m_pTimerAfterCompleteChoiceCtrl, m_pTimerAutoExportCheckBoxCtrl, m_pTimerAutoSaveCheckBoxCtrl, m_pTimerExportPathButtonCtrl, m_pTimerExportPathTextCtrl, m_pTimerSavePathButtonCtrl, m_pTimerSavePathTextCtrl, m_pTimeTextCtrl_Duration, m_pTimeTextCtrl_End, m_pTimeTextCtrl_Start, m_TimeSpan_Duration, mProject, NewPathControl(), S, safenew, wxTextCtrlWrapper::SetReadOnly(), NumericConverter::TIME, wxDateTime_to_AudacityTime(), XO(), and XXO().

Here is the call graph for this function:

◆ PreActionDelay()

ProgressResult TimerRecordDialog::PreActionDelay ( int  iActionIndex,
TimerRecordCompletedActions  eCompletedActions 
)
private

Definition at line 1046 of file TimerRecordDialog.cpp.

1047{
1049 ->GetString(iActionIndex) );
1050
1051 /* i18n-hint: %s is one of "Do nothing", "Exit Audacity", "Restart system",
1052 or "Shutdown system", and
1053 "in" means after a duration of time, shown below this string */
1054 auto sCountdownLabel = XO("%s in:").Format( sAction );
1055
1056 // Two column layout.
1058 {
1059 XO("Timer Recording completed.") ,
1060 {} ,
1061 XO("Recording Saved:") ,
1062 XO("Recording Exported:") ,
1063 XO("Action after Timer Recording:") ,
1064 },
1065 {
1066 {} ,
1067 {} ,
1068 ((eCompletedActions & TR_ACTION_SAVED) ? XO("Yes") : XO("No")) ,
1069 ((eCompletedActions & TR_ACTION_EXPORTED) ? XO("Yes") : XO("No")) ,
1070 sAction ,
1071 },
1072 };
1073
1074
1075 wxDateTime dtNow = wxDateTime::UNow();
1076 wxTimeSpan tsWait = wxTimeSpan(0, 1, 0, 0);
1077 wxDateTime dtActionTime = dtNow.Add(tsWait);
1078
1079 TimerProgressDialog dlgAction(tsWait.GetMilliseconds().GetValue(),
1080 XO("Audacity Timer Record - Waiting"),
1081 columns,
1083 sCountdownLabel);
1084
1085 auto iUpdateResult = ProgressResult::Success;
1086 bool bIsTime = false;
1087 while (iUpdateResult == ProgressResult::Success && !bIsTime)
1088 {
1089 iUpdateResult = dlgAction.UpdateProgress();
1090 using namespace std::chrono;
1091 std::this_thread::sleep_for(kTimerInterval);
1092 bIsTime = (dtActionTime <= wxDateTime::UNow());
1093 }
1094 return iUpdateResult;
1095}
@ pdlgHideStopButton
@ pdlgHideElapsedTime
constexpr auto kTimerInterval
std::vector< MessageColumn > MessageTable

References kTimerInterval, m_pTimerAfterCompleteChoiceCtrl, pdlgHideElapsedTime, pdlgHideStopButton, BasicUI::Success, TR_ACTION_EXPORTED, TR_ACTION_SAVED, TimerProgressDialog::UpdateProgress(), Verbatim(), and XO().

Referenced by ExecutePostRecordActions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RunWaitDialog()

int TimerRecordDialog::RunWaitDialog ( )

Runs the wait for start dialog. Returns false if the user clicks stop.

Runs the wait for start dialog. Returns -1 if the user clicks stop while we are recording or if the post recording actions fail.

Definition at line 480 of file TimerRecordDialog.cpp.

481{
482 auto updateResult = ProgressResult::Success;
483
484 const auto gAudioIO = AudioIO::Get();
485 gAudioIO->DelayActions(true);
486 {
487 auto cleanup = finally([gAudioIO]{ gAudioIO->DelayActions(false); });
488
489 if (m_DateTime_Start > wxDateTime::UNow())
490 updateResult = this->WaitForStart();
491
492 if (updateResult != ProgressResult::Success) {
493 // Don't proceed, but don't treat it as canceled recording. User just canceled waiting.
495 } else {
496 // Record for specified time.
498 bool bIsRecording = true;
499
500 auto sPostAction = Verbatim(
501 m_pTimerAfterCompleteChoiceCtrl->GetStringSelection() );
502
503 // Two column layout.
505 {
506 XO("Recording start:") ,
507 XO("Duration:") ,
508 XO("Recording end:") ,
509 {} ,
510 XO("Automatic Save enabled:") ,
511 XO("Automatic Export enabled:") ,
512 XO("Action after Timer Recording:") ,
513 },
514 {
516 Verbatim( m_TimeSpan_Duration.Format() ),
518 {} ,
519 (m_bAutoSaveEnabled ? XO("Yes") : XO("No")) ,
520 (m_bAutoExportEnabled ? XO("Yes") : XO("No")) ,
521 sPostAction ,
522 }
523 };
524
526 progress(m_TimeSpan_Duration.GetMilliseconds().GetValue(),
527 XO("Audacity Timer Record Progress"),
528 columns,
530
531 // Make sure that start and end time are updated, so we always get the full
532 // duration, even if there's some delay getting here.
533 wxTimerEvent dummyTimerEvent;
534 this->OnTimer(dummyTimerEvent);
535
536 // Loop for progress display during recording.
537 while (bIsRecording && (updateResult == ProgressResult::Success)) {
538 updateResult = progress.UpdateProgress();
539 using namespace std::chrono;
540 std::this_thread::sleep_for(kTimerInterval);
541 bIsRecording = (wxDateTime::UNow() <= m_DateTime_End); // Call UNow() again for extra accuracy...
542 }
543 }
544 }
545
546 // Must do this AFTER the timer project dialog has been deleted to ensure the application
547 // responds to the AUDIOIO events...see not about bug #334 in the ProgressDialog constructor.
549
550 // Let the caller handle cancellation or failure from recording progress.
551 if (updateResult == ProgressResult::Cancelled || updateResult == ProgressResult::Failed)
553
554 return ExecutePostRecordActions((updateResult == ProgressResult::Stopped));
555}
@ pdlgConfirmStopCancel
@ pdlgHideCancelButton
@ POST_TIMER_RECORD_CANCEL
@ POST_TIMER_RECORD_CANCEL_WAIT
static AudioIO * Get()
Definition: AudioIO.cpp:147
void Stop(bool stopStream=true)
static ProjectAudioManager & Get(AudacityProject &project)
void OnRecord(bool altAppearance)
TranslatableString GetDisplayDate(wxDateTime &dt)
int ExecutePostRecordActions(bool bWasStopped)
ProgressResult WaitForStart()

References RefreshCode::Cancelled, ExecutePostRecordActions(), AudioIO::Get(), ProjectAudioManager::Get(), GetDisplayDate(), kTimerInterval, m_bAutoExportEnabled, m_bAutoSaveEnabled, m_DateTime_End, m_DateTime_Start, m_pTimerAfterCompleteChoiceCtrl, m_TimeSpan_Duration, mProject, ProjectAudioManager::OnRecord(), OnTimer(), pdlgConfirmStopCancel, pdlgHideCancelButton, POST_TIMER_RECORD_CANCEL, POST_TIMER_RECORD_CANCEL_WAIT, ProjectAudioManager::Stop(), BasicUI::Success, TimerProgressDialog::UpdateProgress(), Verbatim(), WaitForStart(), and XO().

Referenced by anonymous_namespace{TimerRecordDialog.cpp}::OnTimerRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TransferDataFromWindow()

bool TimerRecordDialog::TransferDataFromWindow ( )
overrideprivate

Definition at line 928 of file TimerRecordDialog.cpp.

929{
930 double dTime;
931 long hr;
932 long min;
933 long sec;
934
937 hr = (long)(dTime / 3600.0);
938 min = (long)((dTime - (hr * 3600.0)) / 60.0);
939 sec = (long)(dTime - (hr * 3600.0) - (min * 60.0));
940 m_DateTime_Start.SetHour(hr);
941 m_DateTime_Start.SetMinute(min);
942 m_DateTime_Start.SetSecond(sec);
943
945 dTime = m_pTimeTextCtrl_End->GetValue();
946 hr = (long)(dTime / 3600.0);
947 min = (long)((dTime - (hr * 3600.0)) / 60.0);
948 sec = (long)(dTime - (hr * 3600.0) - (min * 60.0));
949 m_DateTime_End.SetHour(hr);
950 m_DateTime_End.SetMinute(min);
951 m_DateTime_End.SetSecond(sec);
952
954
955 // Pull the settings from the auto save/export controls and write to the pref file
958
959 // MY: Obtain the index from the choice control so we can save to the prefs file
960 int iPostRecordAction = m_pTimerAfterCompleteChoiceCtrl->GetSelection();
961
962 // Save the options back to the prefs file
963 gPrefs->Write("/TimerRecord/AutoSave", m_bAutoSaveEnabled);
964 gPrefs->Write("/TimerRecord/AutoExport", m_bAutoExportEnabled);
965 gPrefs->Write("/TimerRecord/PostAction", iPostRecordAction);
966
967 return true;
968}

References NumericConverter::GetValue(), gPrefs, m_bAutoExportEnabled, m_bAutoSaveEnabled, m_DateTime_End, m_DateTime_Start, m_pDatePickerCtrl_End, m_pDatePickerCtrl_Start, m_pTimerAfterCompleteChoiceCtrl, m_pTimerAutoExportCheckBoxCtrl, m_pTimerAutoSaveCheckBoxCtrl, m_pTimeTextCtrl_End, m_pTimeTextCtrl_Start, m_TimeSpan_Duration, and min().

Referenced by OnOK().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateDuration()

void TimerRecordDialog::UpdateDuration ( )
private

Definition at line 971 of file TimerRecordDialog.cpp.

References m_DateTime_End, m_DateTime_Start, m_pTimeTextCtrl_Duration, m_TimeSpan_Duration, and NumericTextCtrl::SetValue().

Referenced by OnDatePicker_End().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateEnd()

void TimerRecordDialog::UpdateEnd ( )
private

Definition at line 978 of file TimerRecordDialog.cpp.

979{
980 //v Use remaining disk -> record time calcs from AudacityProject::OnTimer to set range?
982 //wxLogDebug( "Time start %s end %s",
983 // m_DateTime_Start.FormatISOCombined(' '),
984 // m_DateTime_End.FormatISOCombined(' ') );
985
986 // Disable the range limitation (to fix Bug 1749 and 1978)
987 // Otherwise SetVallue asserts when going back in time.
988 m_pDatePickerCtrl_End->SetRange(wxInvalidDateTime, wxInvalidDateTime);
990 // Re-enable range limitation to constrain user input.
991 m_pDatePickerCtrl_End->SetRange(m_DateTime_Start, wxInvalidDateTime); // No backdating.
992 m_pDatePickerCtrl_End->Refresh();
994}

References m_DateTime_End, m_DateTime_Start, m_pDatePickerCtrl_End, m_pTimeTextCtrl_End, m_TimeSpan_Duration, NumericTextCtrl::SetValue(), and wxDateTime_to_AudacityTime().

Referenced by OnDatePicker_Start(), OnTimer(), and OnTimeText_Duration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateTextBoxControls()

void TimerRecordDialog::UpdateTextBoxControls ( )
private

Definition at line 467 of file TimerRecordDialog.cpp.

467 {
468 // Will update the text box controls
469 m_pTimerSavePathTextCtrl->SetValue(m_fnAutoSaveFile.GetFullPath());
470 m_pTimerExportPathTextCtrl->SetValue(m_fnAutoExportFile.GetFullPath());
471
472 // MY: Ensure we still display "Current Project" if this has already been saved
474 m_pTimerSavePathTextCtrl->SetValue(_("Current Project"));
475 }
476}
#define _(s)
Definition: Internat.h:75

References _, m_bProjectAlreadySaved, m_fnAutoExportFile, m_fnAutoSaveFile, m_pTimerExportPathTextCtrl, and m_pTimerSavePathTextCtrl.

Referenced by OnAutoExportPathButton_Click(), and OnAutoSavePathButton_Click().

Here is the caller graph for this function:

◆ WaitForStart()

ProgressResult TimerRecordDialog::WaitForStart ( )
private

Definition at line 996 of file TimerRecordDialog.cpp.

997{
998 // MY: The Waiting For Start dialog now shows what actions will occur after recording has completed
999 auto sPostAction = Verbatim(
1000 m_pTimerAfterCompleteChoiceCtrl->GetStringSelection() );
1001
1002 // Two column layout.
1004 {
1005 XO("Waiting to start recording at:") ,
1006 XO("Recording duration:") ,
1007 XO("Scheduled to stop at:") ,
1008 {} ,
1009 XO("Automatic Save enabled:") ,
1010 XO("Automatic Export enabled:") ,
1011 XO("Action after Timer Recording:") ,
1012 },
1013 {
1015 Verbatim( m_TimeSpan_Duration.Format() ),
1017 {} ,
1018 (m_bAutoSaveEnabled ? XO("Yes") : XO("No")) ,
1019 (m_bAutoExportEnabled ? XO("Yes") : XO("No")) ,
1020 sPostAction ,
1021 },
1022 };
1023
1024 wxDateTime startWait_DateTime = wxDateTime::UNow();
1025 wxTimeSpan waitDuration = m_DateTime_Start - startWait_DateTime;
1026 TimerProgressDialog progress(waitDuration.GetMilliseconds().GetValue(),
1027 XO("Audacity Timer Record - Waiting for Start"),
1028 columns,
1030 /* i18n-hint: "in" means after a duration of time,
1031 which is shown below this string */
1032 XO("Recording will commence in:"));
1033
1034 auto updateResult = ProgressResult::Success;
1035 bool bIsRecording = false;
1036 while (updateResult == ProgressResult::Success && !bIsRecording)
1037 {
1038 updateResult = progress.UpdateProgress();
1039 using namespace std::chrono;
1040 std::this_thread::sleep_for(kTimerInterval);
1041 bIsRecording = (m_DateTime_Start <= wxDateTime::UNow());
1042 }
1043 return updateResult;
1044}

References GetDisplayDate(), kTimerInterval, m_bAutoExportEnabled, m_bAutoSaveEnabled, m_DateTime_End, m_DateTime_Start, m_pTimerAfterCompleteChoiceCtrl, m_TimeSpan_Duration, pdlgConfirmStopCancel, pdlgHideElapsedTime, pdlgHideStopButton, BasicUI::Success, TimerProgressDialog::UpdateProgress(), Verbatim(), and XO().

Referenced by RunWaitDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_bAutoExportEnabled

bool TimerRecordDialog::m_bAutoExportEnabled
private

◆ m_bAutoSaveEnabled

bool TimerRecordDialog::m_bAutoSaveEnabled
private

◆ m_bProjectAlreadySaved

bool TimerRecordDialog::m_bProjectAlreadySaved
private

◆ m_bProjectCleanupRequired

bool TimerRecordDialog::m_bProjectCleanupRequired
private

Definition at line 137 of file TimerRecordDialog.h.

◆ m_DateTime_End

wxDateTime TimerRecordDialog::m_DateTime_End
private

◆ m_DateTime_Start

wxDateTime TimerRecordDialog::m_DateTime_Start
private

◆ m_fnAutoExportFile

wxFileName TimerRecordDialog::m_fnAutoExportFile
private

◆ m_fnAutoSaveFile

wxFileName TimerRecordDialog::m_fnAutoSaveFile
private

◆ m_iAutoExportFilterIndex

int TimerRecordDialog::m_iAutoExportFilterIndex
private

Definition at line 146 of file TimerRecordDialog.h.

Referenced by ExecutePostRecordActions(), and OnAutoExportPathButton_Click().

◆ m_iAutoExportFormat

int TimerRecordDialog::m_iAutoExportFormat
private

Definition at line 144 of file TimerRecordDialog.h.

Referenced by ExecutePostRecordActions(), and OnAutoExportPathButton_Click().

◆ m_iAutoExportSubFormat

int TimerRecordDialog::m_iAutoExportSubFormat
private

Definition at line 145 of file TimerRecordDialog.h.

Referenced by ExecutePostRecordActions(), and OnAutoExportPathButton_Click().

◆ m_pDatePickerCtrl_End

wxDatePickerCtrl* TimerRecordDialog::m_pDatePickerCtrl_End
private

◆ m_pDatePickerCtrl_Start

wxDatePickerCtrl* TimerRecordDialog::m_pDatePickerCtrl_Start
private

◆ m_pTimerAfterCompleteChoiceCtrl

wxChoice* TimerRecordDialog::m_pTimerAfterCompleteChoiceCtrl
private

◆ m_pTimerAutoExportCheckBoxCtrl

wxCheckBox* TimerRecordDialog::m_pTimerAutoExportCheckBoxCtrl
private

◆ m_pTimerAutoSaveCheckBoxCtrl

wxCheckBox* TimerRecordDialog::m_pTimerAutoSaveCheckBoxCtrl
private

◆ m_pTimerExportPathButtonCtrl

wxButton* TimerRecordDialog::m_pTimerExportPathButtonCtrl
private

Definition at line 131 of file TimerRecordDialog.h.

Referenced by EnableDisableAutoControls(), and PopulateOrExchange().

◆ m_pTimerExportPathTextCtrl

wxTextCtrlWrapper* TimerRecordDialog::m_pTimerExportPathTextCtrl
private

◆ m_pTimerSavePathButtonCtrl

wxButton* TimerRecordDialog::m_pTimerSavePathButtonCtrl
private

Definition at line 128 of file TimerRecordDialog.h.

Referenced by EnableDisableAutoControls(), and PopulateOrExchange().

◆ m_pTimerSavePathTextCtrl

wxTextCtrlWrapper* TimerRecordDialog::m_pTimerSavePathTextCtrl
private

◆ m_pTimeTextCtrl_Duration

NumericTextCtrl* TimerRecordDialog::m_pTimeTextCtrl_Duration
private

Definition at line 121 of file TimerRecordDialog.h.

Referenced by OnTimeText_Duration(), PopulateOrExchange(), and UpdateDuration().

◆ m_pTimeTextCtrl_End

NumericTextCtrl* TimerRecordDialog::m_pTimeTextCtrl_End
private

◆ m_pTimeTextCtrl_Start

NumericTextCtrl* TimerRecordDialog::m_pTimeTextCtrl_Start
private

◆ m_timer

wxTimer TimerRecordDialog::m_timer
private

Definition at line 123 of file TimerRecordDialog.h.

Referenced by OnOK().

◆ m_TimeSpan_Duration

wxTimeSpan TimerRecordDialog::m_TimeSpan_Duration
private

◆ mProject

AudacityProject& TimerRecordDialog::mProject
private

The documentation for this class was generated from the following files: