diff --git a/src/AdornedRulerPanel.cpp b/src/AdornedRulerPanel.cpp index dd8bc38e3..9ad0149a9 100644 --- a/src/AdornedRulerPanel.cpp +++ b/src/AdornedRulerPanel.cpp @@ -34,6 +34,7 @@ #include "Project.h" #include "ProjectAudioIO.h" #include "ProjectAudioManager.h" +#include "ProjectStatus.h" #include "ProjectWindow.h" #include "RefreshCode.h" #include "Snap.h" @@ -2207,7 +2208,7 @@ void AdornedRulerPanel::ProcessUIHandleResult void AdornedRulerPanel::UpdateStatusMessage( const wxString &message ) { - GetProject()->SetStatus(message); + ProjectStatus::Get( *GetProject() ).Set(message); } void AdornedRulerPanel::CreateOverlays() diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index f729c632b..32a5b4e7f 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -3390,6 +3390,9 @@ void AudioIO::AllNotesOff(bool looping) // Automated Input Level Adjustment - Automatically tries to find an acceptable input volume #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT + +#include "ProjectStatus.h" + void AudioIO::AILAInitialize() { gPrefs->Read(wxT("/AudioIO/AutomatedInputLevelAdjustment"), &mAILAActive, false); gPrefs->Read(wxT("/AudioIO/TargetPeak"), &mAILAGoalPoint, AILA_DEF_TARGET_PEAK); @@ -3463,7 +3466,7 @@ void AudioIO::AILAProcess(double maxPeak) { //we can't improve it more now if (mAILATotalAnalysis != 0) { mAILAActive = false; - proj->SetStatus(_("Automated Recording Level Adjustment stopped. It was not possible to optimize it more. Still too high.")); + ProjectStatus::Get( *proj ).Set(_("Automated Recording Level Adjustment stopped. It was not possible to optimize it more. Still too high.")); } wxPrintf("\talready min vol:%f\n", iv); } @@ -3472,7 +3475,7 @@ void AudioIO::AILAProcess(double maxPeak) { Px_SetInputVolume(mPortMixer, vol); wxString msg; msg.Printf(_("Automated Recording Level Adjustment decreased the volume to %f."), vol); - proj->SetStatus(msg); + ProjectStatus::Get( *proj ).Set(msg); changetype = 1; wxPrintf("\tnew vol:%f\n", vol); float check = Px_GetInputVolume(mPortMixer); @@ -3486,7 +3489,7 @@ void AudioIO::AILAProcess(double maxPeak) { //we can't improve it more if (mAILATotalAnalysis != 0) { mAILAActive = false; - proj->SetStatus(_("Automated Recording Level Adjustment stopped. It was not possible to optimize it more. Still too low.")); + ProjectStatus::Get( *proj ).Set(_("Automated Recording Level Adjustment stopped. It was not possible to optimize it more. Still too low.")); } wxPrintf("\talready max vol:%f\n", iv); } @@ -3499,7 +3502,7 @@ void AudioIO::AILAProcess(double maxPeak) { Px_SetInputVolume(mPortMixer, vol); wxString msg; msg.Printf(_("Automated Recording Level Adjustment increased the volume to %.2f."), vol); - proj->SetStatus(msg); + ProjectStatus::Get( *proj ).Set(msg); changetype = 2; wxPrintf("\tnew vol:%f\n", vol); float check = Px_GetInputVolume(mPortMixer); @@ -3532,13 +3535,13 @@ void AudioIO::AILAProcess(double maxPeak) { if (mAILAActive && mAILATotalAnalysis != 0 && mAILAAnalysisCounter >= mAILATotalAnalysis) { mAILAActive = false; if (mAILAMax > mAILAGoalPoint + mAILAGoalDelta) - proj->SetStatus(_("Automated Recording Level Adjustment stopped. The total number of analyses has been exceeded without finding an acceptable volume. Still too high.")); + ProjectStatus::Get( *proj ).Set(_("Automated Recording Level Adjustment stopped. The total number of analyses has been exceeded without finding an acceptable volume. Still too high.")); else if (mAILAMax < mAILAGoalPoint - mAILAGoalDelta) - proj->SetStatus(_("Automated Recording Level Adjustment stopped. The total number of analyses has been exceeded without finding an acceptable volume. Still too low.")); + ProjectStatus::Get( *proj ).Set(_("Automated Recording Level Adjustment stopped. The total number of analyses has been exceeded without finding an acceptable volume. Still too low.")); else { wxString msg; msg.Printf(_("Automated Recording Level Adjustment stopped. %.2f seems an acceptable volume."), Px_GetInputVolume(mPortMixer)); - proj->SetStatus(msg); + ProjectStatus::Get( *proj ).Set(msg); } } } diff --git a/src/Project.cpp b/src/Project.cpp index 15481f9f7..646495e61 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -18,7 +18,6 @@ #include #include -wxDEFINE_EVENT(EVT_PROJECT_STATUS_UPDATE, wxCommandEvent); wxDEFINE_EVENT(EVT_TRACK_PANEL_TIMER, wxCommandEvent); size_t AllProjects::size() const @@ -145,17 +144,6 @@ wxString AudacityProject::GetProjectName() const return name; } -// TrackPanel callback method -void AudacityProject::SetStatus(const wxString &msg) -{ - auto &project = *this; - if ( msg != mLastMainStatusMessage ) { - mLastMainStatusMessage = msg; - wxCommandEvent evt{ EVT_PROJECT_STATUS_UPDATE }; - project.ProcessEvent( evt ); - } -} - AUDACITY_DLL_API wxFrame &GetProjectFrame( AudacityProject &project ) { auto ptr = project.GetFrame(); diff --git a/src/Project.h b/src/Project.h index d33003b97..88d552cc3 100644 --- a/src/Project.h +++ b/src/Project.h @@ -29,12 +29,6 @@ AUDACITY_DLL_API AudacityProject *GetActiveProject(); // For use by ProjectManager only: extern void SetActiveProject(AudacityProject * project); -enum StatusBarField { - stateStatusBarField = 1, - mainStatusBarField = 2, - rateStatusBarField = 3 -}; - /// \brief an object of class AllProjects acts like a standard library /// container, but refers to a global array of open projects. So you can /// iterate easily over shared pointers to them with range-for : @@ -96,10 +90,6 @@ using AttachedWindows = ClientData::Site< AudacityProject, wxWindow, ClientData::SkipCopying, wxWeakRef >; -// Type of event emitted by the project when its status message is set -wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, - EVT_PROJECT_STATUS_UPDATE, wxCommandEvent); - wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, EVT_TRACK_PANEL_TIMER, wxCommandEvent); @@ -132,9 +122,6 @@ class AUDACITY_DLL_API AudacityProject final int GetProjectNumber(){ return mProjectNo;} - const wxString &GetStatus() const { return mLastMainStatusMessage; } - void SetStatus(const wxString &msg); - private: // The project's name and file info @@ -148,8 +135,6 @@ class AUDACITY_DLL_API AudacityProject final int mBatchMode{ 0 };// 0 means not, >0 means in batch mode. private: - wxString mLastMainStatusMessage; - wxWeakRef< wxFrame > mFrame{}; }; diff --git a/src/ProjectAudioManager.cpp b/src/ProjectAudioManager.cpp index 6ca9f945e..f5c621ff3 100644 --- a/src/ProjectAudioManager.cpp +++ b/src/ProjectAudioManager.cpp @@ -22,6 +22,7 @@ Paul Licameli split from ProjectManager.cpp #include "ProjectFileIO.h" #include "ProjectHistory.h" #include "ProjectSettings.h" +#include "ProjectStatus.h" #include "ProjectWindow.h" #include "TimeTrack.h" #include "UndoManager.h" diff --git a/src/ProjectFileManager.cpp b/src/ProjectFileManager.cpp index 1f0649ce3..1e59379a6 100644 --- a/src/ProjectFileManager.cpp +++ b/src/ProjectFileManager.cpp @@ -32,6 +32,7 @@ Paul Licameli split from AudacityProject.cpp #include "ProjectHistory.h" #include "ProjectSelectionManager.h" #include "ProjectSettings.h" +#include "ProjectStatus.h" #include "ProjectWindow.h" #include "SelectUtilities.h" #include "SelectionState.h" diff --git a/src/ProjectManager.cpp b/src/ProjectManager.cpp index d942c8a58..2b59882bd 100644 --- a/src/ProjectManager.cpp +++ b/src/ProjectManager.cpp @@ -30,6 +30,7 @@ Paul Licameli split from AudacityProject.cpp #include "ProjectHistory.h" #include "ProjectSelectionManager.h" #include "ProjectSettings.h" +#include "ProjectStatus.h" #include "ProjectWindow.h" #include "SelectUtilities.h" #include "TrackPanel.h" @@ -827,7 +828,7 @@ void ProjectManager::OnStatusChange( wxCommandEvent & ) { auto &project = mProject; auto &window = GetProjectFrame( project ); - const auto &msg = project.GetStatus(); + const auto &msg = ProjectStatus::Get( project ).Get(); window.GetStatusBar()->SetStatusText(msg, mainStatusBarField); // When recording, let the NEW status message stay at least as long as diff --git a/src/ProjectStatus.cpp b/src/ProjectStatus.cpp index e69de29bb..9a7714c8f 100644 --- a/src/ProjectStatus.cpp +++ b/src/ProjectStatus.cpp @@ -0,0 +1,48 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +ProjectStatus.h + +Paul Licameli + +**********************************************************************/ + +#include "ProjectStatus.h" + +#include "Project.h" + +wxDEFINE_EVENT(EVT_PROJECT_STATUS_UPDATE, wxCommandEvent); + +static const AudacityProject::AttachedObjects::RegisteredFactory key{ + []( AudacityProject &parent ){ + return std::make_shared< ProjectStatus >( parent ); + } +}; + +ProjectStatus &ProjectStatus::Get( AudacityProject &project ) +{ + return project.AttachedObjects::Get< ProjectStatus >( key ); +} + +const ProjectStatus &ProjectStatus::Get( const AudacityProject &project ) +{ + return Get( const_cast< AudacityProject & >( project ) ); +} + +ProjectStatus::ProjectStatus( AudacityProject &project ) + : mProject{ project } +{ +} + +ProjectStatus::~ProjectStatus() = default; + +void ProjectStatus::Set(const wxString &msg) +{ + auto &project = mProject; + if ( msg != mLastMainStatusMessage ) { + mLastMainStatusMessage = msg; + wxCommandEvent evt{ EVT_PROJECT_STATUS_UPDATE }; + project.ProcessEvent( evt ); + } +} diff --git a/src/ProjectStatus.h b/src/ProjectStatus.h index e69de29bb..9626e8e17 100644 --- a/src/ProjectStatus.h +++ b/src/ProjectStatus.h @@ -0,0 +1,49 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +ProjectStatus.h + +Paul Licameli + +**********************************************************************/ + +#ifndef __AUDACITY_PROJECT_STATUS__ +#define __AUDACITY_PROJECT_STATUS__ +#endif + +#include // to declare custom event type +#include "ClientData.h" // to inherit + +class AudacityProject; +class wxWindow; + +enum StatusBarField : int { + stateStatusBarField = 1, + mainStatusBarField = 2, + rateStatusBarField = 3 +}; + +// Type of event emitted by the project when its status message is set +wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, + EVT_PROJECT_STATUS_UPDATE, wxCommandEvent); + +class ProjectStatus final + : public ClientData::Base +{ +public: + static ProjectStatus &Get( AudacityProject &project ); + static const ProjectStatus &Get( const AudacityProject &project ); + + explicit ProjectStatus( AudacityProject &project ); + ProjectStatus( const ProjectStatus & ) = delete; + ProjectStatus &operator= ( const ProjectStatus & ) = delete; + ~ProjectStatus() override; + + const wxString &Get() const { return mLastMainStatusMessage; } + void Set(const wxString &msg); + +private: + AudacityProject &mProject; + wxString mLastMainStatusMessage; +}; diff --git a/src/ProjectWindow.cpp b/src/ProjectWindow.cpp index c73c31504..a9e70c3d1 100644 --- a/src/ProjectWindow.cpp +++ b/src/ProjectWindow.cpp @@ -17,6 +17,7 @@ Paul Licameli split from AudacityProject.cpp #include "Menus.h" #include "Project.h" #include "ProjectAudioIO.h" +#include "ProjectStatus.h" #include "RefreshCode.h" #include "TrackPanel.h" #include "TrackPanelMouseEvent.h" diff --git a/src/Screenshot.cpp b/src/Screenshot.cpp index c99253f95..be30763fd 100644 --- a/src/Screenshot.cpp +++ b/src/Screenshot.cpp @@ -39,6 +39,7 @@ It forwards the actual work of doing the commands to the ScreenshotCommand. #include #include "Project.h" +#include "ProjectStatus.h" #include "ProjectWindow.h" #include "Prefs.h" #include "toolbars/ToolManager.h" diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 751ce3492..ed31e3a30 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -56,6 +56,7 @@ is time to refresh some aspect of the screen. #include "ProjectAudioIO.h" #include "ProjectHistory.h" #include "ProjectSettings.h" +#include "ProjectStatus.h" #include "ProjectWindow.h" #include "TrackPanelMouseEvent.h" #include "TrackPanelResizeHandle.h" @@ -673,7 +674,7 @@ void TrackPanel::UpdateStatusMessage( const wxString &st ) if (HasEscape()) /* i18n-hint Esc is a key on the keyboard */ status += wxT(" "), status += _("(Esc to cancel)"); - GetProject()->SetStatus(status); + ProjectStatus::Get( *GetProject() ).Set( status ); } void TrackPanel::UpdateSelectionDisplay() @@ -724,7 +725,8 @@ void TrackPanel::UpdateViewIfNoTracks() mViewInfo->h = 0; mListener->TP_HandleResize(); - GetProject()->SetStatus(wxT("")); //STM: Clear message if all tracks are removed + //STM: Clear message if all tracks are removed + ProjectStatus::Get( *GetProject() ).Set(wxT("")); } } diff --git a/src/menus/TrackMenus.cpp b/src/menus/TrackMenus.cpp index 174e051dc..b7bafdc61 100644 --- a/src/menus/TrackMenus.cpp +++ b/src/menus/TrackMenus.cpp @@ -13,6 +13,7 @@ #include "../ProjectHistory.h" #include "../ProjectSettings.h" #include "../PluginManager.h" +#include "../ProjectStatus.h" #include "../ProjectWindow.h" #include "../SelectUtilities.h" #include "../ShuttleGui.h" @@ -1165,7 +1166,7 @@ void OnTrackClose(const CommandContext &context) if (isAudioActive) { - project.SetStatus( + ProjectStatus::Get( project ).Set( _("Can't delete track with active audio")); wxBell(); return; diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index deb976295..c2d6885ee 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -67,6 +67,7 @@ #include "../ProjectAudioIO.h" #include "../ProjectAudioManager.h" #include "../ProjectSettings.h" +#include "../ProjectStatus.h" #include "../ProjectWindow.h" #include "../ViewInfo.h" #include "../widgets/AButton.h" diff --git a/src/widgets/AButton.cpp b/src/widgets/AButton.cpp index 9b03c3f2d..197077c05 100644 --- a/src/widgets/AButton.cpp +++ b/src/widgets/AButton.cpp @@ -38,6 +38,7 @@ //This is needed for tooltips #include "../Project.h" +#include "../ProjectStatus.h" #include #if wxUSE_ACCESSIBILITY @@ -491,7 +492,7 @@ void AButton::OnMouseEvent(wxMouseEvent & event) if (mCursorIsInWindow) UpdateStatus(); else { - GetActiveProject()->SetStatus(wxT("")); + ProjectStatus::Get( *GetActiveProject() ).Set(wxT("")); } } else @@ -508,7 +509,7 @@ void AButton::UpdateStatus() wxString tipText = pTip->GetTip(); if (!mEnabled) tipText += _(" (disabled)"); - GetActiveProject()->SetStatus(tipText); + ProjectStatus::Get( *GetActiveProject() ).Set(tipText); } #endif } diff --git a/src/widgets/ASlider.cpp b/src/widgets/ASlider.cpp index e41ff9688..dbbdbc077 100644 --- a/src/widgets/ASlider.cpp +++ b/src/widgets/ASlider.cpp @@ -63,6 +63,7 @@ or ASlider. #include "../AColor.h" #include "../ImageManipulation.h" #include "../Project.h" +#include "../ProjectStatus.h" #include "../ShuttleGui.h" #include "../AllThemeResources.h" @@ -1092,7 +1093,7 @@ void LWSlider::OnMouseEvent(wxMouseEvent & event) { // Display the tooltip in the status bar wxString tip = GetTip(mCurrentValue); - GetActiveProject()->SetStatus(tip); + ProjectStatus::Get( *GetActiveProject() ).Set(tip); Refresh(); } else if (event.Leaving()) @@ -1101,7 +1102,7 @@ void LWSlider::OnMouseEvent(wxMouseEvent & event) { ShowTip(false); } - GetActiveProject()->SetStatus(wxT("")); + ProjectStatus::Get( *GetActiveProject() ).Set(wxT("")); Refresh(); } diff --git a/src/widgets/Meter.cpp b/src/widgets/Meter.cpp index 3f452e596..85d6bc5d5 100644 --- a/src/widgets/Meter.cpp +++ b/src/widgets/Meter.cpp @@ -69,6 +69,7 @@ #include "../prefs/GUISettings.h" #include "../Project.h" #include "../ProjectAudioManager.h" +#include "../ProjectStatus.h" #include "../Prefs.h" #include "../ShuttleGui.h" @@ -757,14 +758,14 @@ void MeterPanel::OnMouse(wxMouseEvent &evt) #if wxUSE_TOOLTIPS // Not available in wxX11 if (evt.Leaving()){ - GetActiveProject()->SetStatus(wxT("")); + ProjectStatus::Get( *GetActiveProject() ).Set(wxT("")); } else if (evt.Entering()) { // Display the tooltip in the status bar wxToolTip * pTip = this->GetToolTip(); if( pTip ) { wxString tipText = pTip->GetTip(); - GetActiveProject()->SetStatus(tipText); + ProjectStatus::Get( *GetActiveProject() ).Set(tipText); } } #endif