diff --git a/src/ProjectAudioManager.cpp b/src/ProjectAudioManager.cpp index f5c621ff3..a9edaa3c8 100644 --- a/src/ProjectAudioManager.cpp +++ b/src/ProjectAudioManager.cpp @@ -81,7 +81,8 @@ void ProjectAudioManager::OnAudioIORate(int rate) x+50 }; statusBar->SetStatusWidths(4, widths); - statusBar->SetStatusText(display, rateStatusBarField); + + ProjectStatus::Get( project ).Set( display, rateStatusBarField ); } void ProjectAudioManager::OnAudioIOStartRecording() diff --git a/src/ProjectFileManager.cpp b/src/ProjectFileManager.cpp index 1e59379a6..6db811ead 100644 --- a/src/ProjectFileManager.cpp +++ b/src/ProjectFileManager.cpp @@ -544,8 +544,8 @@ bool ProjectFileManager::DoSave (const bool fromSaveAs, // cancel the cleanup: safetyFileName = wxT(""); - window.GetStatusBar()->SetStatusText( - wxString::Format(_("Saved %s"), fileName), mainStatusBarField); + ProjectStatus::Get( proj ).Set( + wxString::Format(_("Saved %s"), fileName) ); return true; } diff --git a/src/ProjectManager.cpp b/src/ProjectManager.cpp index 2b59882bd..40f6c23fe 100644 --- a/src/ProjectManager.cpp +++ b/src/ProjectManager.cpp @@ -824,17 +824,29 @@ void ProjectManager::OnTimer(wxTimerEvent& WXUNUSED(event)) RestartTimer(); } -void ProjectManager::OnStatusChange( wxCommandEvent & ) +void ProjectManager::OnStatusChange( wxCommandEvent &evt ) { + evt.Skip(); + auto &project = mProject; - auto &window = GetProjectFrame( project ); - const auto &msg = ProjectStatus::Get( project ).Get(); - window.GetStatusBar()->SetStatusText(msg, mainStatusBarField); + + // Be careful to null-check the window. We might get to this function + // during shut-down, but a timer hasn't been told to stop sending its + // messages yet. + auto pWindow = ProjectWindow::Find( &project ); + if ( !pWindow ) + return; + auto &window = *pWindow; + + auto field = static_cast( evt.GetInt() ); + const auto &msg = ProjectStatus::Get( project ).Get( field ); + window.GetStatusBar()->SetStatusText(msg, field); - // When recording, let the NEW status message stay at least as long as - // the timer interval (if it is not replaced again by this function), - // before replacing it with the message about remaining disk capacity. - RestartTimer(); + if ( field == mainStatusBarField ) + // When recording, let the NEW status message stay at least as long as + // the timer interval (if it is not replaced again by this function), + // before replacing it with the message about remaining disk capacity. + RestartTimer(); } wxString ProjectManager::GetHoursMinsString(int iMinutes) diff --git a/src/ProjectStatus.cpp b/src/ProjectStatus.cpp index 9a7714c8f..6eaee1221 100644 --- a/src/ProjectStatus.cpp +++ b/src/ProjectStatus.cpp @@ -37,12 +37,19 @@ ProjectStatus::ProjectStatus( AudacityProject &project ) ProjectStatus::~ProjectStatus() = default; -void ProjectStatus::Set(const wxString &msg) +const wxString &ProjectStatus::Get( StatusBarField field ) const +{ + return mLastStatusMessages[ field - 1 ]; +} + +void ProjectStatus::Set(const wxString &msg, StatusBarField field ) { auto &project = mProject; - if ( msg != mLastMainStatusMessage ) { - mLastMainStatusMessage = msg; + wxString &lastMessage = mLastStatusMessages[ field - 1 ]; + if ( msg != lastMessage ) { + lastMessage = msg; wxCommandEvent evt{ EVT_PROJECT_STATUS_UPDATE }; + evt.SetInt( field ); project.ProcessEvent( evt ); } } diff --git a/src/ProjectStatus.h b/src/ProjectStatus.h index 9626e8e17..cbc0a68b1 100644 --- a/src/ProjectStatus.h +++ b/src/ProjectStatus.h @@ -21,10 +21,13 @@ class wxWindow; enum StatusBarField : int { stateStatusBarField = 1, mainStatusBarField = 2, - rateStatusBarField = 3 + rateStatusBarField = 3, + + nStatusBarFields = 3 }; // Type of event emitted by the project when its status message is set +// GetInt() identifies the intended field of the status bar wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, EVT_PROJECT_STATUS_UPDATE, wxCommandEvent); @@ -40,10 +43,11 @@ public: ProjectStatus &operator= ( const ProjectStatus & ) = delete; ~ProjectStatus() override; - const wxString &Get() const { return mLastMainStatusMessage; } - void Set(const wxString &msg); + const wxString &Get( StatusBarField field = mainStatusBarField ) const; + void Set(const wxString &msg, + StatusBarField field = mainStatusBarField); private: AudacityProject &mProject; - wxString mLastMainStatusMessage; + wxString mLastStatusMessages[ nStatusBarFields ]; }; diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index c2d6885ee..c571df735 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -1431,8 +1431,9 @@ wxString ControlToolBar::StateForStatusBar() void ControlToolBar::UpdateStatusBar() { - GetProjectFrame( mProject ) - .GetStatusBar()->SetStatusText(StateForStatusBar(), stateStatusBarField); + ProjectStatus::Get( mProject ).Set( + StateForStatusBar(), stateStatusBarField + ); } bool ControlToolBar::IsTransportingPinned() const