29#include <wx/wxcrtvararg.h>
31#include <wx/calctrl.h>
32#include <wx/checkbox.h>
36#include <wx/datectrl.h>
37#include <wx/datetime.h>
59#if wxUSE_ACCESSIBILITY
93 return (dateTime.GetHour() * 3600.0) + (dateTime.GetMinute() * 60.0) + dateTime.GetSecond();
105#if wxUSE_ACCESSIBILITY
110 DatePickerCtrlAx(wxDatePickerCtrl * ctrl) :
WindowAccessible(ctrl), mCtrl(ctrl) {};
112 virtual ~ DatePickerCtrlAx() {};
115 wxAccStatus GetState(
int childId,
long *state)
override;
118 wxDatePickerCtrl *mCtrl;
122wxAccStatus DatePickerCtrlAx::GetState(
int WXUNUSED(childId),
long *state)
124 *state = wxACC_STATE_SYSTEM_FOCUSABLE;
125 *state |= (mCtrl == wxWindow::FindFocus() ? wxACC_STATE_SYSTEM_FOCUSED : 0);
158 wxDefaultSize, wxCAPTION)
163 m_DateTime_Start = wxDateTime::UNow();
165 gPrefs->Read(wxT(
"/TimerRecord/LastDuration"), &seconds, 3600);
166 m_TimeSpan_Duration = wxTimeSpan::Seconds(seconds);
167 m_DateTime_End = m_DateTime_Start + m_TimeSpan_Duration;
169 m_pDatePickerCtrl_Start = NULL;
170 m_pTimeTextCtrl_Start = NULL;
172 m_pDatePickerCtrl_End = NULL;
173 m_pTimeTextCtrl_End = NULL;
175 m_pTimeTextCtrl_Duration = NULL;
178 m_bProjectAlreadySaved = bAlreadySaved;
181 this->PopulateOrExchange(
S);
185 m_pTimeTextCtrl_Duration->SetFocus();
186 m_pTimeTextCtrl_Duration->SetFieldFocus(3);
198 wxDateTime dateTime_UNow = wxDateTime::UNow();
211 long hr = (long)(dTime / 3600.0);
212 long min = (long)((dTime - (hr * 3600.0)) / 60.0);
213 long sec = (long)(dTime - (hr * 3600.0) - (
min * 60.0));
220 wxTimerEvent dummyTimerEvent;
221 this->
OnTimer(dummyTimerEvent);
237 long days = (long)(dTime / (24.0 * 3600.0));
239 dTime -= (double)days * 24.0 * 3600.0;
245 wxDateEvent dummyDateEvent;
253 long hr = (long)(dTime / 3600.0);
254 long min = (long)((dTime - (hr * 3600.0)) / 60.0);
255 long sec = (long)(dTime - (hr * 3600.0) - (
min * 60.0));
279 long days = (long)(dTime / (24.0 * 3600.0));
281 dTime -= (double)days * 24.0 * 3600.0;
287 wxDateEvent dummyDateEvent;
294 long hr = (long)(dTime / 3600.0);
295 long min = (long)((dTime - (hr * 3600.0)) / 60.0);
296 long sec = (long)(dTime - (hr * 3600.0) - (
min * 60.0));
307 wxString fName =
SelectFile(FileNames::Operation::Export,
308 XO(
"Save Timer Recording As"),
313 wxFD_SAVE | wxRESIZE_BORDER,
321 if (wxFileExists(fName) && (projectFileIO.GetFileName() != fName)) {
324 XO(
"The selected file name could not be used\nfor Timer Recording because it \
325would overwrite another project.\nPlease try again and select an original name."),
326 XO(
"Error Saving Timer Recording Project"),
346 if (eExporter.SetAutoExportOptions()) {
374 if (!m_TimeSpan_Duration.IsPositive())
377 XO(
"Duration is zero. Nothing will be recorded."),
378 XO(
"Error in Duration"),
379 wxICON_EXCLAMATION | wxOK);
388 XO(
"Automatic Save path is invalid."),
389 XO(
"Error in Automatic Save"),
390 wxICON_EXCLAMATION | wxOK);
397 XO(
"Automatic Export path is invalid."),
398 XO(
"Error in Automatic Export"),
399 wxICON_EXCLAMATION | wxOK);
414 int iMinsLeft = projectManager.GetEstimatedRecordingMinsLeftOnDisk();
420 if (iMinsRecording >= iMinsLeft) {
423 auto sRemainingTime = projectManager.GetHoursMinsString(iMinsLeft);
424 auto sPlannedTime = projectManager.GetHoursMinsString(iMinsRecording);
428"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")
429 .Format( sPlannedTime, sRemainingTime );
434 XO(
"Timer Recording Disk Space Warning"),
435 wxYES_NO | wxNO_DEFAULT | wxICON_WARNING);
436 if (dlgMessage.ShowModal() != wxID_YES ) {
443 this->EndModal(wxID_OK);
446 gPrefs->Write(wxT(
"/TimerRecord/LastDuration"), duration.ToLong());
487 gAudioIO->DelayActions(
true);
489 auto cleanup =
finally([gAudioIO]{ gAudioIO->DelayActions(
false); });
500 bool bIsRecording =
true;
508 XO(
"Recording start:") ,
510 XO(
"Recording end:") ,
512 XO(
"Automatic Save enabled:") ,
513 XO(
"Automatic Export enabled:") ,
514 XO(
"Action after Timer Recording:") ,
529 XO(
"Audacity Timer Record Progress"),
535 wxTimerEvent dummyTimerEvent;
536 this->
OnTimer(dummyTimerEvent);
541 using namespace std::chrono;
570 bool bSaveOK =
false;
571 bool bExportOK =
false;
573 int iOverriddenAction = iPostRecordAction;
574 bool bErrorOverride =
false;
582 bSaveOK = projectFileManager.Save();
591 bExportOK = e.ProcessFromTimerRecording(
599 if (bErrorOverride || bWasStopped) {
606 auto sMessage = (bWasStopped ?
XO(
"Timer Recording stopped.") :
607 XO(
"Timer Recording completed."));
611 sMessage =
XO(
"%s\n\nRecording saved: %s").Format(
614 sMessage =
XO(
"%s\n\nError saving recording.").Format( sMessage );
619 sMessage =
XO(
"%s\n\nRecording exported: %s").Format(
622 sMessage =
XO(
"%s\n\nError exporting recording.").Format( sMessage );
626 if (bErrorOverride) {
628 if ((iOverriddenAction != iPostRecordAction) &&
631 sMessage =
XO(
"%s\n\n'%s' has been canceled due to the error(s) noted above.").Format(
640 wxICON_EXCLAMATION | wxOK);
644 sMessage =
XO(
"%s\n\n'%s' has been canceled as the recording was stopped.").Format(
651 XO(
"Timer Recording"),
652 wxICON_INFORMATION | wxOK);
682 return iPostRecordAction;
687#if defined(__WXMSW__)
699 const wxDateTime::Tm tm(dt.GetTm());
704 st.wYear = (WXWORD)tm.year;
705 st.wMonth = (WXWORD)(tm.mon - wxDateTime::Jan + 1);
707 st.wDayOfWeek = st.wMinute = st.wSecond = st.wMilliseconds = 0;
709 len = ::GetDateFormat(LOCALE_USER_DEFAULT,
716 len = ::GetDateFormat(LOCALE_USER_DEFAULT,
720 wxStringBuffer(s, len),
723 s += wxT(
" ") + dt.FormatTime();
730wxPrintf(wxT(
"%s\n"), dt.Format());
731 return Verbatim( dt.FormatDate() + wxT(
" ") + dt.FormatTime() );
735 wxWindow *wParent,
const int iID,
747 bool bAutoSave =
gPrefs->ReadBool(
"/TimerRecord/AutoSave",
false);
748 bool bAutoExport =
gPrefs->ReadBool(
"/TimerRecord/AutoExport",
false);
749 int iPostTimerRecordAction =
gPrefs->ReadLong(
"/TimerRecord/PostAction", 0);
754 auto strFormat =
XO(
"099 h 060 m 060 s");
756 auto strFormat1 =
XO(
"099 days 024 h 060 m 060 s");
758 S.StartMultiColumn(2, wxCENTER);
760 S.StartVerticalLay(
true);
768 S.StartStatic(
XO(
"Start Date and Time"),
true);
771 safenew wxDatePickerCtrl(
S.GetParent(),
776#if wxUSE_ACCESSIBILITY
779 S.Name(
XO(
"Start Date"))
789 S.Name(
XO(
"Start Time"))
794 S.StartStatic(
XO(
"End Date and Time"),
true);
797 safenew wxDatePickerCtrl(
S.GetParent(),
805#if wxUSE_ACCESSIBILITY
808 S.Name(
XO(
"End Date"))
818 S.Name(
XO(
"End Time"))
823 S.StartStatic(
XO(
"Duration"),
true);
840 S.Name(
XO(
"Duration"))
847 S.StartVerticalLay(
true);
849 S.StartStatic(
XO(
"Automatic Save"),
true);
854 S.StartMultiColumn(3, wxEXPAND);
858 if (!sSaveValue.empty()) {
860 sInitialValue =
XO(
"Current Project");
862 S.AddPrompt(
XXO(
"Save Project As:"));
865 XO(
"Save Project As:"), sInitialValue);
874 S.StartStatic(
XO(
"Automatic Export"),
true);
877 S.StartMultiColumn(3, wxEXPAND);
879 S.AddPrompt(
XXO(
"Export Project As:"));
882 XO(
"Export Project As:"), {});
891 S.StartStatic(
XO(
"Options"),
true);
894 S.StartMultiColumn(1, wxEXPAND);
896 S.SetStretchyCol( 0 );
900 XO(
"Exit Audacity") ,
902 XO(
"Restart system") ,
903 XO(
"Shutdown system") ,
906 iPostTimerRecordAction
923 SetMinSize(GetSize());
939 hr = (long)(dTime / 3600.0);
940 min = (long)((dTime - (hr * 3600.0)) / 60.0);
941 sec = (long)(dTime - (hr * 3600.0) - (
min * 60.0));
948 hr = (long)(dTime / 3600.0);
949 min = (long)((dTime - (hr * 3600.0)) / 60.0);
950 sec = (long)(dTime - (hr * 3600.0) - (
min * 60.0));
967 gPrefs->Write(
"/TimerRecord/PostAction", iPostRecordAction);
1007 XO(
"Waiting to start recording at:") ,
1008 XO(
"Recording duration:") ,
1009 XO(
"Scheduled to stop at:") ,
1011 XO(
"Automatic Save enabled:") ,
1012 XO(
"Automatic Export enabled:") ,
1013 XO(
"Action after Timer Recording:") ,
1026 wxDateTime startWait_DateTime = wxDateTime::UNow();
1029 XO(
"Audacity Timer Record - Waiting for Start"),
1034 XO(
"Recording will commence in:"));
1037 bool bIsRecording =
false;
1041 using namespace std::chrono;
1045 return updateResult;
1051 ->GetString(iActionIndex) );
1056 auto sCountdownLabel =
XO(
"%s in:").Format( sAction );
1061 XO(
"Timer Recording completed.") ,
1063 XO(
"Recording Saved:") ,
1064 XO(
"Recording Exported:") ,
1065 XO(
"Action after Timer Recording:") ,
1077 wxDateTime dtNow = wxDateTime::UNow();
1078 wxTimeSpan tsWait = wxTimeSpan(0, 1, 0, 0);
1079 wxDateTime dtActionTime = dtNow.Add(tsWait);
1082 XO(
"Audacity Timer Record - Waiting"),
1088 bool bIsTime =
false;
1092 using namespace std::chrono;
1094 bIsTime = (dtActionTime <= wxDateTime::UNow());
1096 return iUpdateResult;
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
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)
const int kSlowTimerInterval
@ ID_AUTOEXPORTPATH_BUTTON
constexpr auto kTimerInterval
static double wxDateTime_to_AudacityTime(wxDateTime &dateTime)
TimerRecordCompletedActions
@ POST_TIMER_RECORD_CLOSE
@ POST_TIMER_RECORD_CANCEL
@ POST_TIMER_RECORD_CANCEL_WAIT
@ POST_TIMER_RECORD_NOTHING
declares abstract base class Track, TrackList, and iterators over TrackList
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
Wrap wxMessageDialog so that caption IS translatable.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
FILES_API const FileType AudacityProjects
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
void SetValue(double newValue)
std::vector< MessageColumn > MessageTable
void Stop(bool stopStream=true)
static ProjectAudioManager & Get(AudacityProject &project)
void OnRecord(bool altAppearance)
static ProjectFileIO & Get(AudacityProject &project)
const FilePath & GetFileName() const
static ProjectFileManager & Get(AudacityProject &project)
static ProjectManager & Get(AudacityProject &project)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
ProgressResult UpdateProgress()
Dialog for Timer Record, i.e., timed or long recording.
void OnAutoSaveCheckBox_Change(wxCommandEvent &event)
wxDatePickerCtrl * m_pDatePickerCtrl_Start
NumericTextCtrl * m_pTimeTextCtrl_Duration
wxDateTime m_DateTime_End
void OnHelpButtonClick(wxCommandEvent &event)
void OnTimeText_Duration(wxCommandEvent &event)
NumericTextCtrl * m_pTimeTextCtrl_End
AudacityProject & mProject
TranslatableString GetDisplayDate(wxDateTime &dt)
wxButton * m_pTimerSavePathButtonCtrl
void EnableDisableAutoControls(bool bEnable, int iControlGoup)
wxCheckBox * m_pTimerAutoSaveCheckBoxCtrl
int ExecutePostRecordActions(bool bWasStopped)
void OnOK(wxCommandEvent &event)
void PopulateOrExchange(ShuttleGui &S)
NumericTextCtrl * m_pTimeTextCtrl_Start
wxTextCtrlWrapper * m_pTimerExportPathTextCtrl
wxDateTime m_DateTime_Start
bool m_bAutoExportEnabled
void OnAutoExportPathButton_Click(wxCommandEvent &event)
bool m_bProjectAlreadySaved
void OnAutoExportCheckBox_Change(wxCommandEvent &event)
void UpdateTextBoxControls()
bool TransferDataFromWindow() override
wxChoice * m_pTimerAfterCompleteChoiceCtrl
wxFileName m_fnAutoSaveFile
void OnDatePicker_End(wxDateEvent &event)
ProgressResult WaitForStart()
wxTextCtrlWrapper * NewPathControl(wxWindow *wParent, const int iID, const TranslatableString &sCaption, const TranslatableString &sValue)
int m_iAutoExportSubFormat
wxCheckBox * m_pTimerAutoExportCheckBoxCtrl
wxFileName m_fnAutoExportFile
void OnTimeText_Start(wxCommandEvent &event)
int m_iAutoExportFilterIndex
wxTimeSpan m_TimeSpan_Duration
wxDatePickerCtrl * m_pDatePickerCtrl_End
void OnAutoSavePathButton_Click(wxCommandEvent &event)
wxTextCtrlWrapper * m_pTimerSavePathTextCtrl
void OnTimeText_End(wxCommandEvent &event)
wxButton * m_pTimerExportPathButtonCtrl
void OnTimer(wxTimerEvent &event)
int RunWaitDialog()
Runs the wait for start dialog. Returns false if the user clicks stop.
void OnDatePicker_Start(wxDateEvent &event)
ProgressResult PreActionDelay(int iActionIndex, TimerRecordCompletedActions eCompletedActions)
static TrackList & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
void SetReadOnly(bool readonly=true)