Audacity  3.0.3
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 154 of file TimerRecordDialog.cpp.

156 : wxDialogWrapper(parent, -1, XO("Audacity Timer Record"), wxDefaultPosition,
157  wxDefaultSize, wxCAPTION)
158 , mProject{ project }
159 {
160  SetName();
161 
162  m_DateTime_Start = wxDateTime::UNow();
163  long seconds; // default duration is 1 hour = 3600 seconds
164  gPrefs->Read(wxT("/TimerRecord/LastDuration"), &seconds, 3600);
165  m_TimeSpan_Duration = wxTimeSpan::Seconds(seconds);
167 
169  m_pTimeTextCtrl_Start = NULL;
170 
171  m_pDatePickerCtrl_End = NULL;
172  m_pTimeTextCtrl_End = NULL;
173 
175 
176  // Do we allow the user to change the Automatic Save file?
177  m_bProjectAlreadySaved = bAlreadySaved;
178 
179  ShuttleGui S(this, eIsCreating);
180  this->PopulateOrExchange(S);
181 
182  // Set initial focus to "1" of "01h" in Duration NumericTextCtrl,
183  // instead of OK button (default).
184  m_pTimeTextCtrl_Duration->SetFocus();
186 
187  m_timer.SetOwner(this, TIMER_ID);
189 }

◆ ~TimerRecordDialog()

TimerRecordDialog::~TimerRecordDialog ( )

Definition at line 191 of file TimerRecordDialog.cpp.

192 {
193 }

Member Function Documentation

◆ EnableDisableAutoControls()

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

Definition at line 449 of file TimerRecordDialog.cpp.

449  {
450 
451  if (iControlGoup == CONTROL_GROUP_EXPORT) {
452  m_pTimerExportPathTextCtrl->Enable( bEnable );
453  m_pTimerExportPathButtonCtrl->Enable( bEnable);
454  } else if (iControlGoup == CONTROL_GROUP_SAVE) {
455  m_pTimerSavePathTextCtrl->Enable( bEnable);
456  m_pTimerSavePathButtonCtrl->Enable(bEnable );
457  }
458 
459  // Enable or disable the Choice box - if there is no Save or Export then this will be disabled
460  if (m_pTimerAutoSaveCheckBoxCtrl->GetValue() || m_pTimerAutoExportCheckBoxCtrl->GetValue()) {
462  } else {
465  }
466 }

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?
587  if (m_bAutoExportEnabled) {
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  }
615  if (m_bAutoExportEnabled) {
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 }

References AudacityMessageBox(), ProjectFileManager::Get(), TrackList::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
728 wxPrintf(wxT("%s\n"), dt.Format());
729  return Verbatim( dt.FormatDate() + wxT(" ") + dt.FormatTime() );
730 }

References Verbatim().

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 }

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 361 of file TimerRecordDialog.cpp.

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 340 of file TimerRecordDialog.cpp.

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

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 357 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 302 of file TimerRecordDialog.cpp.

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

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

Here is the call graph for this function:

◆ OnDatePicker_End()

void TimerRecordDialog::OnDatePicker_End ( wxDateEvent &  event)
private

Definition at line 248 of file TimerRecordDialog.cpp.

249 {
251  double dTime = m_pTimeTextCtrl_End->GetValue();
252  long hr = (long)(dTime / 3600.0);
253  long min = (long)((dTime - (hr * 3600.0)) / 60.0);
254  long sec = (long)(dTime - (hr * 3600.0) - (min * 60.0));
255  m_DateTime_End.SetHour(hr);
256  m_DateTime_End.SetMinute(min);
257  m_DateTime_End.SetSecond(sec);
258 
259  // DatePickerCtrls use SetRange to make sure End is never less than Start, but
260  // need to implement it for the TimeTextCtrls.
265  }
266 
267  this->UpdateDuration(); // Keep Start constant and update Duration for changed End.
268 }

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 206 of file TimerRecordDialog.cpp.

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

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 365 of file TimerRecordDialog.cpp.

366 {
367  HelpSystem::ShowHelp(this, L"Timer_Record", true);
368 }

References HelpSystem::ShowHelp().

Here is the call graph for this function:

◆ OnOK()

void TimerRecordDialog::OnOK ( wxCommandEvent &  event)
private

Definition at line 370 of file TimerRecordDialog.cpp.

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

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

Here is the call graph for this function:

◆ OnTimer()

void TimerRecordDialog::OnTimer ( wxTimerEvent &  event)

Definition at line 195 of file TimerRecordDialog.cpp.

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

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 290 of file TimerRecordDialog.cpp.

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

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 270 of file TimerRecordDialog.cpp.

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

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 228 of file TimerRecordDialog.cpp.

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

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"))
779 
782  {}, 0, 44100,
783  Options{}
784  .MenuEnabled(false)
785  .Format(strFormat)
787  S.Name(XO("Start Time"))
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"))
808 
811  {}, 0, 44100,
812  Options{}
813  .MenuEnabled(false)
814  .Format(strFormat)
816  S.Name(XO("End Time"))
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"))
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:"));
863  XO("Save Project As:"), sInitialValue);
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:"));
880  XO("Export Project As:"), {});
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
918 
919  Layout();
920  Fit();
921  SetMinSize(GetSize());
922  Center();
923 
926 }

References ShuttleGuiBase::AddButton(), ShuttleGuiBase::AddCheckBox(), ShuttleGuiBase::AddChoice(), ShuttleGuiBase::AddPrompt(), ShuttleGui::AddStandardButtons(), ShuttleGuiBase::AddWindow(), CONTROL_GROUP_EXPORT, CONTROL_GROUP_SAVE, eCancelButton, eHelpButton, EnableDisableAutoControls(), ShuttleGuiBase::EndMultiColumn(), ShuttleGuiBase::EndStatic(), ShuttleGuiBase::EndVerticalLay(), eOkButton, ProjectFileIO::Get(), ProjectFileIO::GetFileName(), ShuttleGuiBase::GetParent(), gPrefs, ShuttleGui::Id(), 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, ShuttleGui::Name(), NewPathControl(), anonymous_namespace{Menus.cpp}::Options(), safenew, ShuttleGuiBase::SetBorder(), wxTextCtrlWrapper::SetReadOnly(), ShuttleGuiBase::SetStretchyCol(), ShuttleGuiBase::StartMultiColumn(), ShuttleGuiBase::StartStatic(), ShuttleGuiBase::StartVerticalLay(), 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 1045 of file TimerRecordDialog.cpp.

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

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 481 of file TimerRecordDialog.cpp.

482 {
483  auto updateResult = ProgressResult::Success;
484 
485  const auto gAudioIO = AudioIO::Get();
486  gAudioIO->DelayActions(true);
487  {
488  auto cleanup = finally([gAudioIO]{ gAudioIO->DelayActions(false); });
489 
490  if (m_DateTime_Start > wxDateTime::UNow())
491  updateResult = this->WaitForStart();
492 
493  if (updateResult != ProgressResult::Success) {
494  // Don't proceed, but don't treat it as canceled recording. User just canceled waiting.
496  } else {
497  // Record for specified time.
499  bool bIsRecording = true;
500 
501  auto sPostAction = Verbatim(
502  m_pTimerAfterCompleteChoiceCtrl->GetStringSelection() );
503 
504  // Two column layout.
506  {
507  XO("Recording start:") ,
508  XO("Duration:") ,
509  XO("Recording end:") ,
510  {} ,
511  XO("Automatic Save enabled:") ,
512  XO("Automatic Export enabled:") ,
513  XO("Action after Timer Recording:") ,
514  },
515  {
517  Verbatim( m_TimeSpan_Duration.Format() ),
519  {} ,
520  (m_bAutoSaveEnabled ? XO("Yes") : XO("No")) ,
521  (m_bAutoExportEnabled ? XO("Yes") : XO("No")) ,
522  sPostAction ,
523  }
524  };
525 
527  progress(m_TimeSpan_Duration.GetMilliseconds().GetValue(),
528  XO("Audacity Timer Record Progress"),
529  columns,
531 
532  // Make sure that start and end time are updated, so we always get the full
533  // duration, even if there's some delay getting here.
534  wxTimerEvent dummyTimerEvent;
535  this->OnTimer(dummyTimerEvent);
536 
537  // Loop for progress display during recording.
538  while (bIsRecording && (updateResult == ProgressResult::Success)) {
539  updateResult = progress.UpdateProgress();
540  wxMilliSleep(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 }

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 TransportActions::Handler::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 
936  dTime = m_pTimeTextCtrl_Start->GetValue();
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 468 of file TimerRecordDialog.cpp.

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

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  wxMilliSleep(kTimerInterval);
1040  bIsRecording = (m_DateTime_Start <= wxDateTime::UNow());
1041  }
1042  return updateResult;
1043 }

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:
TimerRecordDialog::m_pTimeTextCtrl_Duration
NumericTextCtrl * m_pTimeTextCtrl_Duration
Definition: TimerRecordDialog.h:121
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
TimerRecordDialog::m_timer
wxTimer m_timer
Definition: TimerRecordDialog.h:123
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:38
TimerRecordDialog::m_fnAutoSaveFile
wxFileName m_fnAutoSaveFile
Definition: TimerRecordDialog.h:141
ShuttleGuiBase::AddChoice
wxChoice * AddChoice(const TranslatableString &Prompt, const TranslatableStrings &choices, int Selected=-1)
Definition: ShuttleGui.cpp:398
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1184
TimerRecordDialog::UpdateEnd
void UpdateEnd()
Definition: TimerRecordDialog.cpp:978
ProjectFileIO::GetFileName
const FilePath & GetFileName() const
Definition: ProjectFileIO.cpp:1502
ShuttleGuiBase::AddCheckBox
wxCheckBox * AddCheckBox(const TranslatableString &Prompt, bool Selected)
Definition: ShuttleGui.cpp:309
BasicUI::ProgressResult::Success
@ Success
ProjectAudioManager::Get
static ProjectAudioManager & Get(AudacityProject &project)
Definition: ProjectAudioManager.cpp:55
ProjectAudioManager::OnRecord
void OnRecord(bool altAppearance)
Definition: ProjectAudioManager.cpp:648
TimerRecordDialog::m_pTimerAutoExportCheckBoxCtrl
wxCheckBox * m_pTimerAutoExportCheckBoxCtrl
Definition: TimerRecordDialog.h:129
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Definition: AudacityMessageBox.cpp:17
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
eHelpButton
@ eHelpButton
Definition: ShuttleGui.h:604
ID_AUTOSAVE_CHECKBOX
@ ID_AUTOSAVE_CHECKBOX
Definition: TimerRecordDialog.cpp:74
ID_DATEPICKER_START
@ ID_DATEPICKER_START
Definition: TimerRecordDialog.cpp:65
SelectFile
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
pdlgHideStopButton
@ pdlgHideStopButton
Definition: ProgressDialog.h:38
Exporter
Definition: Export.h:166
TimerRecordDialog::OnDatePicker_Start
void OnDatePicker_Start(wxDateEvent &event)
Definition: TimerRecordDialog.cpp:206
RefreshCode::Cancelled
@ Cancelled
Definition: RefreshCode.h:23
XO
#define XO(s)
Definition: Internat.h:31
ID_AUTOSAVEPATH_TEXT
@ ID_AUTOSAVEPATH_TEXT
Definition: TimerRecordDialog.cpp:71
ProjectFileIO::Get
static ProjectFileIO & Get(AudacityProject &project)
Definition: ProjectFileIO.cpp:266
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1238
TimerRecordDialog::m_pTimerExportPathButtonCtrl
wxButton * m_pTimerExportPathButtonCtrl
Definition: TimerRecordDialog.h:131
TimerRecordDialog::UpdateDuration
void UpdateDuration()
Definition: TimerRecordDialog.cpp:971
NumericTextCtrl
Definition: NumericTextCtrl.h:172
HelpSystem::ShowHelp
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:237
NumericTextCtrl::SetValue
void SetValue(double newValue)
Definition: NumericTextCtrl.cpp:1474
AudacityMessageDialog
Wrap wxMessageDialog so that caption IS translatable.
Definition: wxPanelWrapper.h:215
ID_TIMETEXT_DURATION
@ ID_TIMETEXT_DURATION
Definition: TimerRecordDialog.cpp:69
FileNames::AudacityProjects
FILES_API const FileType AudacityProjects
Definition: FileNames.h:72
TR_ACTION_SAVED
@ TR_ACTION_SAVED
Definition: TimerRecordDialog.h:35
ShuttleGui::Id
ShuttleGui & Id(int id)
Definition: ShuttleGui.cpp:2274
POST_TIMER_RECORD_CLOSE
@ POST_TIMER_RECORD_CLOSE
Definition: TimerRecordDialog.h:45
ID_AUTOEXPORTPATH_BUTTON
@ ID_AUTOEXPORTPATH_BUTTON
Definition: TimerRecordDialog.cpp:72
ID_AUTOEXPORTPATH_TEXT
@ ID_AUTOEXPORTPATH_TEXT
Definition: TimerRecordDialog.cpp:73
TimerRecordDialog::UpdateTextBoxControls
void UpdateTextBoxControls()
Definition: TimerRecordDialog.cpp:468
TimerRecordDialog::m_bAutoExportEnabled
bool m_bAutoExportEnabled
Definition: TimerRecordDialog.h:142
pdlgHideElapsedTime
@ pdlgHideElapsedTime
Definition: ProgressDialog.h:40
TR_ACTION_NOTHING
@ TR_ACTION_NOTHING
Definition: TimerRecordDialog.h:34
ProjectManager::Get
static ProjectManager & Get(AudacityProject &project)
Definition: ProjectManager.cpp:70
TimerRecordDialog::m_bAutoSaveEnabled
bool m_bAutoSaveEnabled
Definition: TimerRecordDialog.h:140
wxTextCtrlWrapper
Definition: wxTextCtrlWrapper.h:23
XXO
#define XXO(s)
Definition: Internat.h:44
eCancelButton
@ eCancelButton
Definition: ShuttleGui.h:601
TimerRecordDialog::ExecutePostRecordActions
int ExecutePostRecordActions(bool bWasStopped)
Definition: TimerRecordDialog.cpp:557
ID_TIMETEXT_START
@ ID_TIMETEXT_START
Definition: TimerRecordDialog.cpp:66
kSlowTimerInterval
const int kSlowTimerInterval
Definition: TimerRecordDialog.cpp:85
POST_TIMER_RECORD_NOTHING
@ POST_TIMER_RECORD_NOTHING
Definition: TimerRecordDialog.h:44
TR_ACTION_EXPORTED
@ TR_ACTION_EXPORTED
Definition: TimerRecordDialog.h:36
ID_DATEPICKER_END
@ ID_DATEPICKER_END
Definition: TimerRecordDialog.cpp:67
ProjectFileManager::Get
static ProjectFileManager & Get(AudacityProject &project)
Definition: ProjectFileManager.cpp:66
TimerRecordDialog::NewPathControl
wxTextCtrlWrapper * NewPathControl(wxWindow *wParent, const int iID, const TranslatableString &sCaption, const TranslatableString &sValue)
Definition: TimerRecordDialog.cpp:732
TimerRecordDialog::m_iAutoExportFilterIndex
int m_iAutoExportFilterIndex
Definition: TimerRecordDialog.h:146
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1229
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1203
TimerProgressDialog
Definition: ProgressDialog.h:152
wxDateTime_to_AudacityTime
static double wxDateTime_to_AudacityTime(wxDateTime &dateTime)
Definition: TimerRecordDialog.cpp:90
TimerRecordDialog::WaitForStart
ProgressResult WaitForStart()
Definition: TimerRecordDialog.cpp:996
ProgressDialog::MessageTable
std::vector< MessageColumn > MessageTable
Definition: ProgressDialog.h:62
TimerRecordDialog::m_pTimerSavePathTextCtrl
wxTextCtrlWrapper * m_pTimerSavePathTextCtrl
Definition: TimerRecordDialog.h:127
pdlgConfirmStopCancel
@ pdlgConfirmStopCancel
Definition: ProgressDialog.h:41
TimerRecordDialog::m_pTimerSavePathButtonCtrl
wxButton * m_pTimerSavePathButtonCtrl
Definition: TimerRecordDialog.h:128
NumericConverter::TIME
@ TIME
Definition: NumericTextCtrl.h:52
ShuttleGuiBase::GetParent
wxWindow * GetParent()
Definition: ShuttleGui.h:496
TimerRecordDialog::m_DateTime_Start
wxDateTime m_DateTime_Start
Definition: TimerRecordDialog.h:110
@0::kTimerInterval
@ kTimerInterval
ShuttleGuiBase::AddWindow
wxWindow * AddWindow(wxWindow *pWindow, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:299
TimerRecordDialog::PreActionDelay
ProgressResult PreActionDelay(int iActionIndex, TimerRecordCompletedActions eCompletedActions)
Definition: TimerRecordDialog.cpp:1045
TimerRecordDialog::m_bProjectAlreadySaved
bool m_bProjectAlreadySaved
Definition: TimerRecordDialog.h:147
ID_AUTOSAVEPATH_BUTTON
@ ID_AUTOSAVEPATH_BUTTON
Definition: TimerRecordDialog.cpp:70
TimerRecordDialog::m_pDatePickerCtrl_Start
wxDatePickerCtrl * m_pDatePickerCtrl_Start
Definition: TimerRecordDialog.h:115
TimerRecordDialog::mProject
AudacityProject & mProject
Definition: TimerRecordDialog.h:108
TimerRecordDialog::m_DateTime_End
wxDateTime m_DateTime_End
Definition: TimerRecordDialog.h:111
ProjectAudioManager::Stop
void Stop(bool stopStream=true)
Definition: ProjectAudioManager.cpp:495
TimerRecordDialog::OnTimer
void OnTimer(wxTimerEvent &event)
Definition: TimerRecordDialog.cpp:195
TimerRecordDialog::OnDatePicker_End
void OnDatePicker_End(wxDateEvent &event)
Definition: TimerRecordDialog.cpp:248
CONTROL_GROUP_EXPORT
@ CONTROL_GROUP_EXPORT
Definition: TimerRecordDialog.cpp:80
ShuttleGuiBase::AddButton
wxButton * AddButton(const TranslatableString &Text, int PositionFlags=wxALIGN_CENTRE, bool setDefault=false)
Definition: ShuttleGui.cpp:360
ShuttleGuiBase::StartStatic
wxStaticBox * StartStatic(const TranslatableString &Str, int iProp=0)
Definition: ShuttleGui.cpp:893
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
ID_AUTOEXPORT_CHECKBOX
@ ID_AUTOEXPORT_CHECKBOX
Definition: TimerRecordDialog.cpp:75
ShuttleGui::Name
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:663
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
eOkButton
@ eOkButton
Definition: ShuttleGui.h:600
NumericTextCtrl::SetFieldFocus
void SetFieldFocus(int)
Definition: NumericTextCtrl.cpp:2048
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
TimerRecordDialog::EnableDisableAutoControls
void EnableDisableAutoControls(bool bEnable, int iControlGoup)
Definition: TimerRecordDialog.cpp:449
POST_TIMER_RECORD_CANCEL
@ POST_TIMER_RECORD_CANCEL
Definition: TimerRecordDialog.h:42
_
#define _(s)
Definition: Internat.h:75
TIMER_ID
#define TIMER_ID
Definition: TimerRecordDialog.cpp:62
TimerRecordDialog::m_pTimeTextCtrl_Start
NumericTextCtrl * m_pTimeTextCtrl_Start
Definition: TimerRecordDialog.h:116
TimerRecordCompletedActions
TimerRecordCompletedActions
Definition: TimerRecordDialog.h:33
wxTextCtrlWrapper::SetReadOnly
void SetReadOnly(bool readonly=true)
Definition: wxTextCtrlWrapper.h:66
TimerRecordDialog::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S)
Definition: TimerRecordDialog.cpp:743
TimerRecordDialog::m_iAutoExportSubFormat
int m_iAutoExportSubFormat
Definition: TimerRecordDialog.h:145
Verbatim
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
Definition: TranslatableString.h:321
TimerRecordDialog::m_pDatePickerCtrl_End
wxDatePickerCtrl * m_pDatePickerCtrl_End
Definition: TimerRecordDialog.h:118
TimerRecordDialog::m_pTimerAfterCompleteChoiceCtrl
wxChoice * m_pTimerAfterCompleteChoiceCtrl
Definition: TimerRecordDialog.h:134
wxDialogWrapper::wxDialogWrapper
wxDialogWrapper()
Definition: wxPanelWrapper.h:84
TimerRecordDialog::m_TimeSpan_Duration
wxTimeSpan m_TimeSpan_Duration
Definition: TimerRecordDialog.h:112
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2444
TimerRecordDialog::m_fnAutoExportFile
wxFileName m_fnAutoExportFile
Definition: TimerRecordDialog.h:143
ShuttleGuiBase::AddPrompt
void AddPrompt(const TranslatableString &Prompt, int wrapWidth=0)
Right aligned text string.
Definition: ShuttleGui.cpp:238
TimerRecordDialog::m_pTimeTextCtrl_End
NumericTextCtrl * m_pTimeTextCtrl_End
Definition: TimerRecordDialog.h:119
TranslatableString::Translation
wxString Translation() const
Definition: TranslatableString.h:79
ShuttleGuiBase::SetBorder
void SetBorder(int Border)
Definition: ShuttleGui.h:489
wxDialogWrapper::SetName
void SetName()
Definition: wxPanelWrapper.cpp:81
TimerRecordDialog::GetDisplayDate
TranslatableString GetDisplayDate(wxDateTime &dt)
Definition: TimerRecordDialog.cpp:683
POST_TIMER_RECORD_CANCEL_WAIT
@ POST_TIMER_RECORD_CANCEL_WAIT
Definition: TimerRecordDialog.h:41
ShuttleGuiBase::EndStatic
void EndStatic()
Definition: ShuttleGui.cpp:922
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:141
safenew
#define safenew
Definition: MemoryX.h:10
ShuttleGuiBase::SetStretchyCol
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:202
TimerRecordDialog::m_iAutoExportFormat
int m_iAutoExportFormat
Definition: TimerRecordDialog.h:144
NumericConverter::GetValue
double GetValue()
Definition: NumericTextCtrl.cpp:1174
anonymous_namespace{Menus.cpp}::Options
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:527
TimerRecordDialog::m_pTimerExportPathTextCtrl
wxTextCtrlWrapper * m_pTimerExportPathTextCtrl
Definition: TimerRecordDialog.h:130
TimerRecordDialog::m_pTimerAutoSaveCheckBoxCtrl
wxCheckBox * m_pTimerAutoSaveCheckBoxCtrl
Definition: TimerRecordDialog.h:126
pdlgHideCancelButton
@ pdlgHideCancelButton
Definition: ProgressDialog.h:39
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
ID_TIMETEXT_END
@ ID_TIMETEXT_END
Definition: TimerRecordDialog.cpp:68
CONTROL_GROUP_SAVE
@ CONTROL_GROUP_SAVE
Definition: TimerRecordDialog.cpp:79
TimerRecordDialog::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: TimerRecordDialog.cpp:928