diff --git a/lib-src/mod-null/ModNullCallback.cpp b/lib-src/mod-null/ModNullCallback.cpp index 936d246f7..d201c3419 100644 --- a/lib-src/mod-null/ModNullCallback.cpp +++ b/lib-src/mod-null/ModNullCallback.cpp @@ -152,7 +152,7 @@ int ModuleDispatch(ModuleDispatchTypes type) if( p== NULL ) return 0; - wxMenuBar * pBar = p->GetMenuBar(); + wxMenuBar * pBar = GetProjectFrame( *p ).GetMenuBar(); wxMenu * pMenu = pBar->GetMenu( 8 ); // Menu 8 is the Analyze Menu. CommandManager * c = &CommandManager::Get( *p ); diff --git a/src/AdornedRulerPanel.cpp b/src/AdornedRulerPanel.cpp index 3741cb095..a1bf9c7e2 100644 --- a/src/AdornedRulerPanel.cpp +++ b/src/AdornedRulerPanel.cpp @@ -844,7 +844,7 @@ namespace{ AudacityProject::AttachedWindows::RegisteredFactory sKey{ []( AudacityProject &project ) -> wxWeakRef< wxWindow > { auto &viewInfo = ViewInfo::Get( project ); - auto &window = project; + auto &window = ProjectWindow::Get( project ); return safenew AdornedRulerPanel( &project, window.GetTopPanel(), wxID_ANY, diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index b4581a024..568663d6a 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -956,9 +956,10 @@ void AudacityApp::OnTimer(wxTimerEvent& WXUNUSED(event)) // Get the users attention AudacityProject *project = GetActiveProject(); if (project) { - project->Maximize(); - project->Raise(); - project->RequestUserAttention(); + auto &window = GetProjectFrame( *project ); + window.Maximize(); + window.Raise(); + window.RequestUserAttention(); } continue; } @@ -989,8 +990,9 @@ void AudacityApp::OnTimer(wxTimerEvent& WXUNUSED(event)) // if there are no projects open, don't show the warning (user has closed it) if (offendingProject) { - offendingProject->Iconize(false); - offendingProject->Raise(); + auto &window = GetProjectFrame( *offendingProject ); + window.Iconize(false); + window.Raise(); wxString errorMessage = wxString::Format(_( "One or more external audio files could not be found.\n\ @@ -1074,7 +1076,7 @@ bool AudacityApp::OnExceptionInMainLoop() // Forget pending changes in the TrackList TrackList::Get( *pProject ).ClearPendingTracks(); - pProject->RedrawProject(); + ProjectWindow::Get( *pProject ).RedrawProject(); } // Give the user an alert @@ -1512,8 +1514,9 @@ bool AudacityApp::OnInit() wxWindow * pWnd = MakeHijackPanel(); if (pWnd) { - project->Show(false); - pWnd->SetParent(project); + auto &window = GetProjectFrame( *project ); + window.Show(false); + pWnd->SetParent( &window ); SetTopWindow(pWnd); pWnd->Show(true); } diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 546afeb96..46e2e4083 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -1700,7 +1700,8 @@ void AudioIO::StartMonitoring(double sampleRate) if (!success) { wxString msg = wxString::Format(_("Error opening recording device.\nError code: %s"), gAudioIO->LastPaErrorString()); - ShowErrorDialog(mOwningProject, _("Error"), msg, wxT("Error_opening_sound_device")); + ShowErrorDialog( ProjectWindow::Find( mOwningProject ), + _("Error"), msg, wxT("Error_opening_sound_device")); return; } diff --git a/src/BatchProcessDialog.cpp b/src/BatchProcessDialog.cpp index 6ea378727..a56b5712d 100644 --- a/src/BatchProcessDialog.cpp +++ b/src/BatchProcessDialog.cpp @@ -462,7 +462,7 @@ void ApplyMacroDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event)) auto success = GuardedCall< bool >( [&] { project->Import(files[i]); - project->ZoomAfterImport(nullptr); + ProjectWindow::Get( *project ).ZoomAfterImport(nullptr); SelectActions::DoSelectAll(*project); if (!mMacroCommands.ApplyMacro(mCatalog)) return false; diff --git a/src/Dependencies.cpp b/src/Dependencies.cpp index 1831974e8..9ec79db0f 100644 --- a/src/Dependencies.cpp +++ b/src/Dependencies.cpp @@ -597,6 +597,7 @@ void DependencyDialog::SaveFutureActionChoice() bool ShowDependencyDialogIfNeeded(AudacityProject *project, bool isSaving) { + auto pWindow = ProjectWindow::Find( project ); AliasedFileArray aliasedFiles; FindDependencies(project, aliasedFiles); @@ -611,7 +612,7 @@ you may lose data."); AudacityMessageBox(msg, _("Dependency Check"), wxOK | wxICON_INFORMATION, - project); + pWindow); } return true; // Nothing to do. } @@ -633,7 +634,7 @@ you may lose data."); return true; } - DependencyDialog dlog(project, -1, project, aliasedFiles, isSaving); + DependencyDialog dlog(pWindow, -1, project, aliasedFiles, isSaving); int returnCode = dlog.ShowModal(); if (returnCode == wxID_CANCEL) return false; diff --git a/src/LabelDialog.cpp b/src/LabelDialog.cpp index 5626064ea..4f84be66a 100644 --- a/src/LabelDialog.cpp +++ b/src/LabelDialog.cpp @@ -746,7 +746,7 @@ void LabelDialog::OnSelectCell(wxGridEvent &event) RowData &rd = mData[event.GetRow()]; mViewInfo->selectedRegion = rd.selectedRegion; - GetActiveProject()->RedrawProject(); + ProjectWindow::Get( *GetActiveProject() ).RedrawProject(); } event.Skip(); diff --git a/src/LabelTrack.cpp b/src/LabelTrack.cpp index 65917f9af..7d97b9b87 100644 --- a/src/LabelTrack.cpp +++ b/src/LabelTrack.cpp @@ -2180,7 +2180,7 @@ void LabelTrack::ShowContextMenu() // Bug 2044. parent can be nullptr after a context switch. if( !parent ) - parent = GetActiveProject(); + parent = FindProjectFrame( GetActiveProject() ); if( parent ) { @@ -3091,8 +3091,9 @@ void LabelTrack::DoEditLabels auto &trackFactory = TrackFactory::Get( project ); auto rate = project.GetRate(); auto &viewInfo = ViewInfo::Get( project ); + auto &window = ProjectWindow::Get( project ); - LabelDialog dlg(&project, trackFactory, &tracks, + LabelDialog dlg(&window, trackFactory, &tracks, lt, index, viewInfo, rate, format, freqFormat); @@ -3102,7 +3103,7 @@ void LabelTrack::DoEditLabels if (dlg.ShowModal() == wxID_OK) { project.PushState(_("Edited labels"), _("Label")); - project.RedrawProject(); + window.RedrawProject(); } } @@ -3121,7 +3122,8 @@ int LabelTrack::DialogForLabelName( -40; position.y += 2; // just below the bottom of the track position = trackPanel.ClientToScreen(position); - AudacityTextEntryDialog dialog{ &project, + auto &window = GetProjectFrame( project ); + AudacityTextEntryDialog dialog{ &window, _("Name:"), _("New label"), initialValue, @@ -3130,7 +3132,7 @@ int LabelTrack::DialogForLabelName( // keep the dialog within Audacity's window, so that the dialog is always fully visible wxRect dialogScreenRect = dialog.GetScreenRect(); - wxRect projScreenRect = project.GetScreenRect(); + wxRect projScreenRect = window.GetScreenRect(); wxPoint max = projScreenRect.GetBottomRight() + wxPoint{ -dialogScreenRect.width, -dialogScreenRect.height }; if (dialogScreenRect.x > max.x) { position.x = max.x; diff --git a/src/LyricsWindow.cpp b/src/LyricsWindow.cpp index 0a9b99a3f..070e49a09 100644 --- a/src/LyricsWindow.cpp +++ b/src/LyricsWindow.cpp @@ -44,8 +44,8 @@ END_EVENT_TABLE() const wxSize gSize = wxSize(LYRICS_DEFAULT_WIDTH, LYRICS_DEFAULT_HEIGHT); -LyricsWindow::LyricsWindow(AudacityProject *parent): - wxFrame(parent, -1, +LyricsWindow::LyricsWindow(AudacityProject *parent) + : wxFrame( &GetProjectFrame( *parent ), -1, wxString::Format(_("Audacity Karaoke%s"), ((parent->GetProjectName().empty()) ? wxT("") : diff --git a/src/Menus.cpp b/src/Menus.cpp index 2f4db1e55..eb676278b 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -51,6 +51,7 @@ #include "widgets/FileHistory.h" #include +#include MenuCreator::MenuCreator() { @@ -302,7 +303,7 @@ void MenuCreator::CreateMenusAndCommands(AudacityProject &project) VisitItem( project, menuTree.get() ); - project.SetMenuBar(menubar.release()); + GetProjectFrame( project ).SetMenuBar(menubar.release()); mLastFlags = AlwaysEnabledFlag; @@ -361,8 +362,9 @@ void MenuCreator::RebuildMenuBar(AudacityProject &project) // Delete the menus, since we will soon recreate them. // Rather oddly, the menus don't vanish as a result of doing this. { - std::unique_ptr menuBar{ project.GetMenuBar() }; - project.DetachMenuBar(); + auto &window = ProjectWindow::Get( project ); + wxWindowPtr menuBar{ window.GetMenuBar() }; + window.DetachMenuBar(); // menuBar gets deleted here } @@ -411,7 +413,8 @@ CommandFlag MenuManager::GetUpdateFlags static auto lastFlags = flags; // if (auto focus = wxWindow::FindFocus()) { - if (wxWindow * focus = &project) { + auto &window = GetProjectFrame( project ); + if (wxWindow * focus = &window) { while (focus && focus->GetParent()) focus = focus->GetParent(); if (focus && !static_cast(focus)->IsIconized()) @@ -430,7 +433,7 @@ CommandFlag MenuManager::GetUpdateFlags flags |= NotPausedFlag; // quick 'short-circuit' return. - if ( checkActive && !project.IsActive() ){ + if ( checkActive && !window.IsActive() ){ const auto checkedFlags = NotMinimizedFlag | AudioIONotBusyFlag | AudioIOBusyFlag | PausedFlag | NotPausedFlag; @@ -749,9 +752,10 @@ void MenuCreator::RebuildAllMenuBars() // http://bugzilla.audacityteam.org/show_bug.cgi?id=458 // // This workaround should be removed when Audacity updates to wxWidgets 3.x which has a fix. - wxRect r = p->GetRect(); - p->SetSize(wxSize(1,1)); - p->SetSize(r.GetSize()); + auto &window = GetProjectFrame( *p ); + wxRect r = window.GetRect(); + window.SetSize(wxSize(1,1)); + window.SetSize(r.GetSize()); #endif } } diff --git a/src/MissingAliasFileDialog.cpp b/src/MissingAliasFileDialog.cpp index bfbc7a746..c4bf2328e 100644 --- a/src/MissingAliasFileDialog.cpp +++ b/src/MissingAliasFileDialog.cpp @@ -36,8 +36,9 @@ MissingAliasFileDialog::MissingAliasFileDialog(wxWindow *parent, const wxString & dlogTitle, const wxString & message, const wxString & helpURL, - const bool Close, const bool modal): -ErrorDialog(parent, dlogTitle, message, helpURL, Close, modal) + const bool Close, const bool modal) +: ErrorDialog( parent, + dlogTitle, message, helpURL, Close, modal ) { sDialogs.push_back( this ); } @@ -62,12 +63,13 @@ namespace MissingAliasFilesDialog { using Lock = std::unique_lock< std::mutex >; - void Show(AudacityProject *parent, + void Show(AudacityProject *project, const wxString &dlogTitle, const wxString &message, const wxString &helpPage, const bool Close) { + auto parent = FindProjectFrame( project ); wxASSERT(parent); // to justify safenew ErrorDialog *dlog = safenew MissingAliasFileDialog(parent, dlogTitle, message, helpPage, Close, false); // Don't center because in many cases (effect, export, etc) there will be a progress bar in the center that blocks this. @@ -92,10 +94,11 @@ namespace MissingAliasFilesDialog { wxDialog *Find( const AudacityProject &project ) { + auto &window = GetProjectFrame( project ); auto begin = sDialogs.begin(), end = sDialogs.end(), iter = std::find_if( begin, end, [&]( const wxDialogRef &ref ){ - return ref && ref->GetParent() == &project; } ); + return ref && ref->GetParent() == &window; } ); if (iter != end) return *iter; return nullptr; diff --git a/src/MixerBoard.cpp b/src/MixerBoard.cpp index c46d3d78c..ee976222c 100644 --- a/src/MixerBoard.cpp +++ b/src/MixerBoard.cpp @@ -748,9 +748,7 @@ void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event)) // Update the TrackPanel correspondingly. if (mProject->IsSoloSimple()) - { - mProject->RedrawProject(); - } + ProjectWindow::Get( *mProject ).RedrawProject(); else // Update only the changed track. TrackPanel::Get( *mProject ).RefreshTrack(mTrack.get()); @@ -765,7 +763,7 @@ void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event)) // Update the TrackPanel correspondingly. // Bug 509: Must repaint all, as many tracks can change with one Solo change. - mProject->RedrawProject(); + ProjectWindow::Get( *mProject ).RedrawProject(); } @@ -1397,7 +1395,7 @@ const wxSize kDefaultSize = wxSize(MIXER_BOARD_MIN_WIDTH, MIXER_BOARD_MIN_HEIGHT); MixerBoardFrame::MixerBoardFrame(AudacityProject* parent) -: wxFrame(parent, -1, +: wxFrame( &GetProjectFrame( *parent ), -1, wxString::Format(_("Audacity Mixer Board%s"), ((parent->GetProjectName().empty()) ? wxT("") : diff --git a/src/Project.cpp b/src/Project.cpp index 1b0d798da..f3ec0ea24 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -184,11 +184,11 @@ bool AllProjects::Close( bool force ) // of deletion from gAudacityProjects if ( force ) { - gAudacityProjects[0]->Close(true); + GetProjectFrame( *gAudacityProjects[0] ).Close(true); } else { - if (!gAudacityProjects[0]->Close()) + if (! GetProjectFrame( *gAudacityProjects[0] ).Close()) return false; } } @@ -202,14 +202,15 @@ void AllProjects::SaveWindowSize() return; } bool validWindowForSaveWindowSize = FALSE; - AudacityProject * validProject = NULL; + ProjectWindow * validProject = nullptr; bool foundIconizedProject = FALSE; size_t numProjects = gAudacityProjects.size(); for (size_t i = 0; i < numProjects; i++) { - if (!gAudacityProjects[i]->IsIconized()) { + auto &window = ProjectWindow::Get( *gAudacityProjects[i] ); + if (!window.IsIconized()) { validWindowForSaveWindowSize = TRUE; - validProject = gAudacityProjects[i].get(); + validProject = &window; i = numProjects; } else @@ -235,7 +236,7 @@ void AllProjects::SaveWindowSize() else { if (foundIconizedProject) { - validProject = gAudacityProjects[0].get(); + validProject = &ProjectWindow::Get( *gAudacityProjects[0] ); bool wndMaximized = validProject->IsMaximized(); wxRect normalRect = validProject->GetNormalizedWindowState(); // store only the normal rectangle because the itemized rectangle @@ -403,7 +404,7 @@ void SetActiveProject(AudacityProject * project) gActiveProject = project; KeyboardCapture::Capture( nullptr ); } - wxTheApp->SetTopWindow(project); + wxTheApp->SetTopWindow( FindProjectFrame( project ) ); } #if wxUSE_DRAG_AND_DROP @@ -552,7 +553,7 @@ public: ODManager::Pauser pauser; auto cleanup = finally( [&] { - mProject->HandleResize(); // Adjust scrollers for NEW track sizes. + ProjectWindow::Get( *mProject ).HandleResize(); // Adjust scrollers for NEW track sizes. } ); for (const auto &name : sortednames) { @@ -564,7 +565,8 @@ public: mProject->Import(name); } - mProject->ZoomAfterImport(nullptr); + auto &window = ProjectWindow::Get( *mProject ); + window.ZoomAfterImport(nullptr); return true; } ); @@ -669,17 +671,19 @@ AudacityProject *CreateNewAudacityProject() Destroyer< AudacityProject > {} } ); const auto p = gAudacityProjects.back().get(); + auto &project = *p; + auto &window = GetProjectFrame( *p ); // wxGTK3 seems to need to require creating the window using default position // and then manually positioning it. - p->SetPosition(wndRect.GetPosition()); + window.SetPosition(wndRect.GetPosition()); if(bMaximized) { - p->Maximize(true); + window.Maximize(true); } else if (bIconized) { // if the user close down and iconized state we could start back up and iconized state - // p->Iconize(TRUE); + // window.Iconize(TRUE); } //Initialise the Listener @@ -694,7 +698,7 @@ AudacityProject *CreateNewAudacityProject() ModuleManager::Get().Dispatch(ProjectInitialized); - p->Show(true); + window.Show(true); return p; } @@ -703,21 +707,21 @@ void RedrawAllProjects() { size_t len = gAudacityProjects.size(); for (size_t i = 0; i < len; i++) - gAudacityProjects[i]->RedrawProject(); + ProjectWindow::Get( *gAudacityProjects[i] ).RedrawProject(); } void RefreshCursorForAllProjects() { size_t len = gAudacityProjects.size(); for (size_t i = 0; i < len; i++) - gAudacityProjects[i]->RefreshCursor(); + ProjectWindow::Get( *gAudacityProjects[i] ).RefreshCursor(); } AUDACITY_DLL_API void CloseAllProjects() { size_t len = gAudacityProjects.size(); for (size_t i = 0; i < len; i++) - gAudacityProjects[i]->Close(); + GetProjectFrame( *gAudacityProjects[i] ).Close(); //Set the Offset and Position increments to 0 gAudacityOffsetInc = 0; @@ -904,12 +908,12 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) } bool validWindowSize = false; - AudacityProject * validProject = NULL; + ProjectWindow * validProject = NULL; size_t numProjects = gAudacityProjects.size(); for (int i = numProjects; i > 0 ; i--) { - if (!gAudacityProjects[i-1]->IsIconized()) { + if (!GetProjectFrame( *gAudacityProjects[i-1] ).IsIconized()) { validWindowSize = true; - validProject = gAudacityProjects[i-1].get(); + validProject = &ProjectWindow::Get( *gAudacityProjects[i-1] ); break; } } @@ -1439,7 +1443,7 @@ void AudacityProject::OnThemeChange(wxCommandEvent& evt) { evt.Skip(); auto &project = *this; - ApplyUpdatedTheme(); + ProjectWindow::Get( project ).ApplyUpdatedTheme(); auto &toolManager = ToolManager::Get( project ); for( int ii = 0; ii < ToolBarCount; ++ii ) { @@ -2144,7 +2148,7 @@ void AudacityProject::RefreshAllTitles(bool bShowProjectNumbers ) { for ( size_t i = 0; i < gAudacityProjects.size(); i++) { if ( gAudacityProjects[i] ) { - if ( !gAudacityProjects[i]->mIconized ) { + if ( !GetProjectFrame( *gAudacityProjects[i] ).IsIconized() ) { AudacityProject * p; p = gAudacityProjects[i].get(); p->SetProjectTitle( bShowProjectNumbers ? p->GetProjectNumber() : -1 ); @@ -2169,7 +2173,7 @@ void AudacityProject::OnIconize(wxIconizeEvent &event) // It's not used outside this function. for(i=0;imIconized ) + if( !GetProjectFrame( *gAudacityProjects[i] ).IsIconized() ) VisibleProjectCount++; } } @@ -2418,9 +2422,10 @@ void AudacityProject::OnMouseEvent(wxMouseEvent & event) class TitleRestorer{ public: TitleRestorer(AudacityProject * p ){ - if( p->IsIconized() ) - p->Restore(); - p->Raise(); // May help identifying the window on Mac + auto &window = GetProjectFrame( *p ); + if( window.IsIconized() ) + window.Restore(); + window.Raise(); // May help identifying the window on Mac // Construct this projects name and number. sProjName = p->GetProjectName(); @@ -2881,11 +2886,15 @@ AudacityProject *AudacityProject::OpenProject( AudacityProject *pNewProject = nullptr; if ( ! pProject ) pProject = pNewProject = CreateNewAudacityProject(); - auto cleanup = finally( [&] { if( pNewProject ) pNewProject->Close(true); } ); + auto cleanup = finally( [&] { + if( pNewProject ) + GetProjectFrame( *pNewProject ).Close(true); + } ); pProject->OpenFile( fileNameArg, addtohistory ); pNewProject = nullptr; if( pProject && pProject->mIsRecovered ) - pProject->Zoom( ViewActions::GetZoomOfToFit( *pProject ) ); + ProjectWindow::Get( *pProject ).Zoom( + ViewActions::GetZoomOfToFit( *pProject ) ); return pProject; } @@ -3385,6 +3394,7 @@ void AudacityProject::EnqueueODTasks() bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs) { auto &project = *this; + auto &window = ProjectWindow::Get( project ); auto &viewInfo = ViewInfo::Get( project ); auto &dirManager = DirManager::Get( project ); bool bFileVersionFound = false; @@ -3527,7 +3537,7 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs) if (longVpos != 0) { // PRL: It seems this must happen after SetSnapTo viewInfo.vpos = longVpos; - mbInitializingScrollbar = true; + window.mbInitializingScrollbar = true; } // Specifically detect newer versions of Audacity @@ -3786,7 +3796,7 @@ bool AudacityProject::DoSave (const bool fromSaveAs, // See explanation above // ProjectDisabler disabler(this); auto &proj = *this; - auto &window = proj; + auto &window = GetProjectFrame( proj ); auto &dirManager = DirManager::Get( proj ); wxASSERT_MSG(!bWantSaveCopy || fromSaveAs, "Copy Project SHOULD only be availabele from SaveAs"); @@ -5089,7 +5099,7 @@ void AudacityProject::MayStartMonitoring() void AudacityProject::OnAudioIORate(int rate) { auto &project = *this; - auto &window = project; + auto &window = GetProjectFrame( project ); wxString display; if (rate > 0) { display = wxString::Format(_("Actual Rate: %d"), rate); @@ -5123,6 +5133,7 @@ void AudacityProject::OnAudioIOStopRecording() { auto &project = *this; auto &dirManager = DirManager::Get( project ); + auto &window = ProjectWindow::Get( project ); // Only push state if we were capturing and not monitoring if (GetAudioIOToken() > 0) @@ -5147,7 +5158,7 @@ void AudacityProject::OnAudioIOStopRecording() interval.first + interval.second }, wxString::Format(wxT("%ld"), counter++), -2 ); - ShowWarningDialog(this, wxT("DropoutDetected"), _("\ + ShowWarningDialog(&window, wxT("DropoutDetected"), _("\ Recorded audio was lost at the labeled locations. Possible causes:\n\ \n\ Other applications are competing with Audacity for processor time\n\ @@ -5170,8 +5181,8 @@ You are saving directly to a slow external storage device\n\ } // Refresh the project window - FixScrollbars(); - RedrawProject(); + window.FixScrollbars(); + window.RedrawProject(); } // Write all cached files to disk, if any @@ -5421,7 +5432,7 @@ void AudacityProject::PlaybackScroller::OnTimer(wxCommandEvent &event) } viewInfo.h = viewInfo.OffsetTimeByPixels(viewInfo.h, deltaX, true); - if (!mProject->MayScrollBeyondZero()) + if (!ProjectWindow::Get( *mProject ).MayScrollBeyondZero()) // Can't scroll too far left viewInfo.h = std::max(0.0, viewInfo.h); trackPanel.Refresh(false); diff --git a/src/Project.h b/src/Project.h index e45ce968e..2b5717041 100644 --- a/src/Project.h +++ b/src/Project.h @@ -165,6 +165,7 @@ using AttachedWindows = ClientData::Site< AudacityProject, wxWindow, ClientData::SkipCopying, wxWeakRef >; +using ProjectWindow = AudacityProject; class AUDACITY_DLL_API AudacityProject final : public wxFrame, public TrackPanelListener, public SelectionBarListener, @@ -176,6 +177,12 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame, , public AttachedWindows { public: + static ProjectWindow &Get( AudacityProject &project ) { return project; } + static const ProjectWindow &Get( const AudacityProject &project ) { return project; } + static ProjectWindow *Find( AudacityProject *pProject ) { return pProject; } + static const ProjectWindow *Find( const AudacityProject *pProject ) { return pProject; } + AudacityProject &GetProject() { return *this; } + using AttachedObjects = ::AttachedObjects; using AttachedWindows = ::AttachedWindows; @@ -648,6 +655,17 @@ public: DECLARE_EVENT_TABLE() }; +inline wxFrame &GetProjectFrame( AudacityProject &project ) { return project; } +inline const wxFrame &GetProjectFrame( const AudacityProject &project ) { + return project; +} +inline wxFrame *FindProjectFrame( AudacityProject *project ) { + return project ? &GetProjectFrame( *project ) : nullptr; +} +inline const wxFrame *FindProjectFrame( const AudacityProject *project ) { + return project ? &GetProjectFrame( *project ) : nullptr; +} + AudioIOStartStreamOptions DefaultPlayOptions( AudacityProject &project ); AudioIOStartStreamOptions DefaultSpeedPlayOptions( AudacityProject &project ); diff --git a/src/Screenshot.cpp b/src/Screenshot.cpp index 28ca3299f..ec91227dd 100644 --- a/src/Screenshot.cpp +++ b/src/Screenshot.cpp @@ -470,7 +470,7 @@ void ScreenFrame::PopulateOrExchange(ShuttleGui & S) CentreOnParent(); } - SetIcon(mContext.project.GetIcon()); + SetIcon( GetProjectFrame( mContext.project ).GetIcon() ); } bool ScreenFrame::ProcessEvent(wxEvent & e) @@ -565,8 +565,9 @@ void ScreenFrame::SizeMainWindow(int w, int h) { int top = 20; - mContext.project.Maximize(false); - mContext.project.SetSize(16, 16 + top, w, h); + auto &window = GetProjectFrame( mContext.project ); + window.Maximize(false); + window.SetSize(16, 16 + top, w, h); //Bug383 - Toolbar Resets not wanted. //ToolManager::Get( mContext.project ).Reset(); } @@ -670,10 +671,11 @@ void ScreenFrame::OnCaptureSomething(wxCommandEvent & event) void ScreenFrame::TimeZoom(double seconds) { auto &viewInfo = ViewInfo::Get( mContext.project ); + auto &window = ProjectWindow::Get( mContext.project ); int width, height; - mContext.project.GetClientSize(&width, &height); + window.GetClientSize(&width, &height); viewInfo.SetZoom((0.75 * width) / seconds); - mContext.project.RedrawProject(); + window.RedrawProject(); } void ScreenFrame::OnOneSec(wxCommandEvent & WXUNUSED(event)) @@ -718,7 +720,7 @@ void ScreenFrame::SizeTracks(int h) for (auto channel : channels) channel->SetHeight(height); } - mContext.project.RedrawProject(); + ProjectWindow::Get( mContext.project ).RedrawProject(); } void ScreenFrame::OnShortTracks(wxCommandEvent & WXUNUSED(event)) @@ -726,7 +728,7 @@ void ScreenFrame::OnShortTracks(wxCommandEvent & WXUNUSED(event)) for (auto t : TrackList::Get( mContext.project ).Any()) t->SetHeight(t->GetMinimizedHeight()); - mContext.project.RedrawProject(); + ProjectWindow::Get( mContext.project ).RedrawProject(); } void ScreenFrame::OnMedTracks(wxCommandEvent & WXUNUSED(event)) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index ae4c35c19..c2741b312 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -213,7 +213,7 @@ AudacityProject::AttachedWindows::RegisteredFactory sKey{ []( AudacityProject &project ) -> wxWeakRef< wxWindow > { auto &ruler = AdornedRulerPanel::Get( project ); auto &viewInfo = ViewInfo::Get( project ); - auto &window = project; + auto &window = ProjectWindow::Get( project ); auto mainPage = window.GetMainPage(); wxASSERT( mainPage ); // to justify safenew @@ -263,7 +263,7 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id, AdornedRulerPanel * ruler) : CellularPanel(parent, id, pos, size, viewInfo, wxWANTS_CHARS | wxNO_BORDER), - mListener(project), + mListener( &ProjectWindow::Get( *project ) ), mTracks(tracks), mRuler(ruler), mTrackArtist(nullptr), @@ -299,7 +299,8 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id, mTimeCount = 0; mTimer.parent = this; // Timer is started after the window is visible - GetProject()->Bind(wxEVT_IDLE, &TrackPanel::OnIdle, this); + ProjectWindow::Get( *GetProject() ).Bind(wxEVT_IDLE, + &TrackPanel::OnIdle, this); // Register for tracklist updates mTracks->Bind(EVT_TRACKLIST_RESIZING, @@ -417,9 +418,9 @@ AudacityProject * TrackPanel::GetProject() const #endif pWind = pWind->GetParent(); //MainPanel wxASSERT( pWind ); - pWind = pWind->GetParent(); //Project + pWind = pWind->GetParent(); //ProjectWindow wxASSERT( pWind ); - return (AudacityProject*)pWind; + return &static_cast( pWind )->GetProject(); } void TrackPanel::OnIdle(wxIdleEvent& event) @@ -430,7 +431,8 @@ void TrackPanel::OnIdle(wxIdleEvent& event) mTimer.Start(kTimerInterval, FALSE); // Timer is started, we don't need the event anymore - GetProject()->Unbind(wxEVT_IDLE, &TrackPanel::OnIdle, this); + GetProjectFrame( *GetProject() ).Unbind(wxEVT_IDLE, + &TrackPanel::OnIdle, this); } else { @@ -450,14 +452,16 @@ void TrackPanel::OnTimer(wxTimerEvent& ) // us a deactivate event for the application. { auto project = GetProject(); - if (project->IsIconized()) - project->MacShowUndockedToolbars(false); + auto &window = ProjectWindow::Get( *project ); + if (window.IsIconized()) + window.MacShowUndockedToolbars(false); } #endif mTimeCount++; AudacityProject *const p = GetProject(); + auto &window = ProjectWindow::Get( *p ); // Check whether we were playing or recording, but the stream has stopped. if (p->GetAudioIOToken()>0 && !IsAudioActive()) @@ -473,9 +477,9 @@ void TrackPanel::OnTimer(wxTimerEvent& ) if (p->GetAudioIOToken()>0 && !gAudioIO->IsAudioTokenActive(p->GetAudioIOToken())) { - p->FixScrollbars(); + window.FixScrollbars(); p->SetAudioIOToken(0); - p->RedrawProject(); + window.RedrawProject(); mRedrawAfterStop = false; @@ -2762,7 +2766,8 @@ LWSlider * TrackInfo::GainSlider gGainCaptured->Set(gain); auto slider = (captured ? gGainCaptured : gGain).get(); - slider->SetParent( pParent ? pParent : ::GetActiveProject() ); + slider->SetParent( pParent ? pParent : + FindProjectFrame( ::GetActiveProject() ) ); return slider; } @@ -2778,7 +2783,8 @@ LWSlider * TrackInfo::PanSlider gPanCaptured->Set(pan); auto slider = (captured ? gPanCaptured : gPan).get(); - slider->SetParent( pParent ? pParent : ::GetActiveProject() ); + slider->SetParent( pParent ? pParent : + FindProjectFrame( ::GetActiveProject() ) ); return slider; } @@ -2795,7 +2801,8 @@ LWSlider * TrackInfo::VelocitySlider gVelocityCaptured->Set(velocity); auto slider = (captured ? gVelocityCaptured : gVelocity).get(); - slider->SetParent( pParent ? pParent : ::GetActiveProject() ); + slider->SetParent( pParent ? pParent : + FindProjectFrame( ::GetActiveProject() ) ); return slider; } #endif diff --git a/src/commands/CommandHandler.cpp b/src/commands/CommandHandler.cpp index bd7336e39..4f98a636a 100644 --- a/src/commands/CommandHandler.cpp +++ b/src/commands/CommandHandler.cpp @@ -59,5 +59,5 @@ void CommandHandler::OnReceiveCommand(AppCommandEvent &event) wxUnusedVar(result); // Redraw the project - context.project.RedrawProject(); + ProjectWindow::Get( context.project ).RedrawProject(); } diff --git a/src/commands/CommandManager.cpp b/src/commands/CommandManager.cpp index bb4aa7053..54991f599 100644 --- a/src/commands/CommandManager.cpp +++ b/src/commands/CommandManager.cpp @@ -1119,6 +1119,7 @@ wxString CommandManager::DescribeCommandsAndShortcuts /// bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent & evt, bool permit) { + auto pWindow = FindProjectFrame( project ); CommandListEntry *entry = mCommandKeyHash[KeyEventToKeyString(evt)]; if (entry == NULL) { @@ -1141,10 +1142,10 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent & wxWindow * pFocus = wxWindow::FindFocus(); wxWindow * pParent = wxGetTopLevelParent( pFocus ); - bool validTarget = pParent == project; + bool validTarget = pParent == pWindow; // Bug 1557. MixerBoard should count as 'destined for project' // MixerBoard IS a TopLevelWindow, and its parent is the project. - if( pParent && pParent->GetParent() == project){ + if( pParent && pParent->GetParent() == pWindow ){ if( dynamic_cast< TopLevelKeystrokeHandlingWindow* >( pParent ) != NULL ) validTarget = true; } @@ -1280,7 +1281,8 @@ bool CommandManager::HandleMenuID(int id, CommandFlag flags, CommandMask mask) // Only want one page of the preferences PrefsDialog::Factories factories; factories.push_back(KeyConfigPrefsFactory( entry->name )); - GlobalPrefsDialog dialog(GetActiveProject(), factories); + auto pWindow = FindProjectFrame( GetActiveProject() ); + GlobalPrefsDialog dialog( pWindow, factories ); dialog.ShowModal(); MenuCreator::RebuildAllMenuBars(); return true; @@ -1654,7 +1656,7 @@ static struct InstallHandlers // We must have a project since we will be working with the // CommandManager, which is tied to individual projects. AudacityProject *project = GetActiveProject(); - return project && project->IsEnabled(); + return project && GetProjectFrame( *project ).IsEnabled(); } ); KeyboardCapture::SetPostFilter( []( wxKeyEvent &key ) { // Capture handler window didn't want it, so ask the CommandManager. diff --git a/src/commands/DragCommand.cpp b/src/commands/DragCommand.cpp index 5d66614e8..053900247 100644 --- a/src/commands/DragCommand.cpp +++ b/src/commands/DragCommand.cpp @@ -90,7 +90,7 @@ bool DragCommand::Apply(const CommandContext & context) if( !bHasToY ) mToY = 10; - wxWindow * pWin = &context.project; + wxWindow * pWin = &GetProjectFrame( context.project ); wxWindow * pWin1 = nullptr; wxMouseEvent Evt( wxEVT_MOTION ); Evt.m_x = mFromX; diff --git a/src/commands/GetInfoCommand.cpp b/src/commands/GetInfoCommand.cpp index 6405955a6..ed82087c7 100644 --- a/src/commands/GetInfoCommand.cpp +++ b/src/commands/GetInfoCommand.cpp @@ -159,7 +159,7 @@ bool GetInfoCommand::ApplyInner(const CommandContext &context) bool GetInfoCommand::SendMenus(const CommandContext &context) { - wxMenuBar * pBar = context.project.GetMenuBar(); + wxMenuBar * pBar = GetProjectFrame( context.project ).GetMenuBar(); if(!pBar ){ wxLogDebug("No menus"); return false; @@ -418,12 +418,12 @@ wxSpinCtrl * ShuttleGuiGetDefinition::TieSpinCtrl( bool GetInfoCommand::SendPreferences(const CommandContext &context) { context.StartArray(); - GlobalPrefsDialog dialog( &context.project ); + auto pWin = &GetProjectFrame( context.project ); + GlobalPrefsDialog dialog( pWin ); // wxCommandEvent Evt; //dialog.Show(); - wxWindow * pWin = &context.project; ShuttleGuiGetDefinition S(pWin, *((context.pOutput)->mStatusTarget) ); - dialog.ShuttleAll( S ); + dialog.ShuttleAll( S ); context.EndArray(); return true; } @@ -454,7 +454,7 @@ bool GetInfoCommand::SendCommands(const CommandContext &context, int flags ) bool GetInfoCommand::SendBoxes(const CommandContext &context) { //context.Status("Boxes"); - wxWindow * pWin = &context.project; + auto pWin = &GetProjectFrame( context.project ); context.StartArray(); wxRect R = pWin->GetScreenRect(); diff --git a/src/commands/ScreenshotCommand.cpp b/src/commands/ScreenshotCommand.cpp index a185753ea..d38d0c548 100644 --- a/src/commands/ScreenshotCommand.cpp +++ b/src/commands/ScreenshotCommand.cpp @@ -150,7 +150,7 @@ void IdleHandler(wxIdleEvent& event){ wxTopLevelWindow *ScreenshotCommand::GetFrontWindow(AudacityProject *project) { wxWindow *front = NULL; - wxWindow *proj = wxGetTopLevelParent(project); + wxWindow *proj = wxGetTopLevelParent( ProjectWindow::Find( project ) ); // JKC: The code below is no longer such a good idea. @@ -795,7 +795,7 @@ wxRect ScreenshotCommand::GetTrackRect( AudacityProject * pProj, TrackPanel * pa } wxString ScreenshotCommand::WindowFileName(AudacityProject * proj, wxTopLevelWindow *w){ - if (w != proj && !w->GetTitle().empty()) { + if (w != ProjectWindow::Find( proj ) && !w->GetTitle().empty()) { mFileName = MakeFileName(mFilePath, kCaptureWhatStrings[ mCaptureMode ].Translation() + (wxT("-") + w->GetTitle() + wxT("-"))); diff --git a/src/commands/SetProjectCommand.cpp b/src/commands/SetProjectCommand.cpp index 1dc9259fc..3955a45d9 100644 --- a/src/commands/SetProjectCommand.cpp +++ b/src/commands/SetProjectCommand.cpp @@ -66,20 +66,21 @@ void SetProjectCommand::PopulateOrExchange(ShuttleGui & S) bool SetProjectCommand::Apply(const CommandContext & context) { - AudacityProject * pProj = &context.project; + auto &project = context.project; + auto &window = GetProjectFrame( project ); if( bHasName ) - pProj->SetLabel(mName); + window.SetLabel(mName); if( bHasRate && mRate >= 1 && mRate <= 1000000 ) { - auto &bar = SelectionBar::Get( *pProj ); + auto &bar = SelectionBar::Get( project ); bar.SetRate( mRate ); } if( bHasSizing ) { - pProj->SetPosition( wxPoint( mPosX, mPosY)); - pProj->SetSize( wxSize( mWidth, mHeight )); + window.SetPosition( wxPoint( mPosX, mPosY)); + window.SetSize( wxSize( mWidth, mHeight )); } return true; } diff --git a/src/effects/EffectRack.cpp b/src/effects/EffectRack.cpp index b69e8fa19..7031fadec 100644 --- a/src/effects/EffectRack.cpp +++ b/src/effects/EffectRack.cpp @@ -76,7 +76,7 @@ BEGIN_EVENT_TABLE(EffectRack, wxFrame) END_EVENT_TABLE() EffectRack::EffectRack() -: wxFrame(GetActiveProject(), +: wxFrame( FindProjectFrame( GetActiveProject() ), wxID_ANY, _("Effects Rack"), wxDefaultPosition, diff --git a/src/export/Export.cpp b/src/export/Export.cpp index f4f825cf2..98e85fc7c 100644 --- a/src/export/Export.cpp +++ b/src/export/Export.cpp @@ -334,7 +334,7 @@ void Exporter::OnExtensionChanged(wxCommandEvent &evt) { void Exporter::OnHelp(wxCommandEvent& WXUNUSED(evt)) { - wxWindow * pWin = GetActiveProject(); + wxWindow * pWin = FindProjectFrame( GetActiveProject() ); HelpSystem::ShowHelp(pWin, wxT("File_Export_Dialog"), true); } @@ -572,7 +572,7 @@ bool Exporter::GetFilename() auto useFileName = mFilename; if (!useFileName.HasExt()) useFileName.SetExt(defext); - FileDialogWrapper fd(mProject, + FileDialogWrapper fd( ProjectWindow::Find( mProject ), mFileDialogTitle, mFilename.GetPath(), useFileName.GetFullName(), @@ -813,22 +813,23 @@ bool Exporter::CheckMix() if (exportFormat != wxT("CL") && exportFormat != wxT("FFMPEG") && exportedChannels == -1) exportedChannels = mChannels; + auto pWindow = ProjectWindow::Find( mProject ); if (exportedChannels == 1) { - if (ShowWarningDialog(mProject, + if (ShowWarningDialog(pWindow, wxT("MixMono"), _("Your tracks will be mixed down and exported as one mono file."), true) == wxID_CANCEL) return false; } else if (exportedChannels == 2) { - if (ShowWarningDialog(mProject, + if (ShowWarningDialog(pWindow, wxT("MixStereo"), _("Your tracks will be mixed down and exported as one stereo file."), true) == wxID_CANCEL) return false; } else { - if (ShowWarningDialog(mProject, + if (ShowWarningDialog(pWindow, wxT("MixUnknownChannels"), _("Your tracks will be mixed down to one exported file according to the encoder settings."), true) == wxID_CANCEL) diff --git a/src/export/ExportMP3.cpp b/src/export/ExportMP3.cpp index d18a05dba..f702de175 100644 --- a/src/export/ExportMP3.cpp +++ b/src/export/ExportMP3.cpp @@ -1755,7 +1755,7 @@ ProgressResult ExportMP3::Export(AudacityProject *project, { int rate = lrint(project->GetRate()); #ifndef DISABLE_DYNAMIC_LOADING_LAME - wxWindow *parent = project; + wxWindow *parent = ProjectWindow::Find( project ); #endif // DISABLE_DYNAMIC_LOADING_LAME const auto &tracks = TrackList::Get( *project ); MP3Exporter exporter; diff --git a/src/export/ExportMultiple.cpp b/src/export/ExportMultiple.cpp index cd10b25cc..c07c6a305 100644 --- a/src/export/ExportMultiple.cpp +++ b/src/export/ExportMultiple.cpp @@ -127,7 +127,8 @@ BEGIN_EVENT_TABLE(MouseEvtHandler, wxEvtHandler) END_EVENT_TABLE() ExportMultiple::ExportMultiple(AudacityProject *project) -: wxDialogWrapper(project, wxID_ANY, wxString(_("Export Multiple"))) +: wxDialogWrapper( &GetProjectFrame( *project ), + wxID_ANY, wxString(_("Export Multiple")) ) , mSelectionState{ SelectionState::Get( *project ) } { SetName(GetTitle()); @@ -740,7 +741,9 @@ ProgressResult ExportMultiple::ExportMultipleByLabel(bool byName, // let the user have a crack at editing it, exit if cancelled bool bShowTagsDialog = mProject->GetShowId3Dialog(); if( bShowTagsDialog ){ - bool bCancelled = !setting.filetags.ShowEditDialog(mProject,_("Edit Metadata Tags"), bShowTagsDialog); + bool bCancelled = !setting.filetags.ShowEditDialog( + ProjectWindow::Find( mProject ), + _("Edit Metadata Tags"), bShowTagsDialog); gPrefs->Read(wxT("/AudioFiles/ShowId3Dialog"), &bShowTagsDialog, true); mProject->SetShowId3Dialog( bShowTagsDialog ); if( bCancelled ) @@ -857,7 +860,9 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName, // let the user have a crack at editing it, exit if cancelled bool bShowTagsDialog = mProject->GetShowId3Dialog(); if( bShowTagsDialog ){ - bool bCancelled = !setting.filetags.ShowEditDialog(mProject,_("Edit Metadata Tags"), bShowTagsDialog); + bool bCancelled = !setting.filetags.ShowEditDialog( + ProjectWindow::Find( mProject ), + _("Edit Metadata Tags"), bShowTagsDialog); gPrefs->Read(wxT("/AudioFiles/ShowId3Dialog"), &bShowTagsDialog, true); mProject->SetShowId3Dialog( bShowTagsDialog ); if( bCancelled ) diff --git a/src/import/ImportLOF.cpp b/src/import/ImportLOF.cpp index 239cbe180..ba6f41990 100644 --- a/src/import/ImportLOF.cpp +++ b/src/import/ImportLOF.cpp @@ -472,13 +472,13 @@ void LOFImportFileHandle::doDurationAndScrollOffset() if (callDurationFactor) { double longestDuration = TrackList::Get( *mProject ).GetEndTime(); - mProject->ZoomBy(longestDuration / durationFactor); + ProjectWindow::Get( *mProject ).ZoomBy(longestDuration / durationFactor); callDurationFactor = false; } if (callScrollOffset && (scrollOffset != 0)) { - mProject->TP_ScrollWindow(scrollOffset); + ProjectWindow::Get( *mProject ).TP_ScrollWindow(scrollOffset); callScrollOffset = false; } diff --git a/src/menus/EditMenus.cpp b/src/menus/EditMenus.cpp index f52e07cb6..dae27b0b9 100644 --- a/src/menus/EditMenus.cpp +++ b/src/menus/EditMenus.cpp @@ -37,6 +37,7 @@ bool DoPasteText(AudacityProject &project) auto &tracks = TrackList::Get( project ); auto &trackPanel = TrackPanel::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); for (auto pLabelTrack : tracks.Any()) { @@ -56,7 +57,7 @@ bool DoPasteText(AudacityProject &project) } // Redraw everyting (is that necessary???) and bail - project.RedrawProject(); + window.RedrawProject(); return true; } } @@ -73,6 +74,7 @@ bool DoPasteNothingSelected(AudacityProject &project) auto &trackFactory = TrackFactory::Get( project ); auto &trackPanel = TrackPanel::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); // First check whether anything's selected. if (tracks.Selected()) @@ -147,7 +149,7 @@ bool DoPasteNothingSelected(AudacityProject &project) project.PushState(_("Pasted from the clipboard"), _("Paste")); - project.RedrawProject(); + window.RedrawProject(); if (pFirstNewTrack) trackPanel.EnsureVisible(pFirstNewTrack); @@ -168,7 +170,7 @@ void DoReloadPreferences( AudacityProject &project ) SpectrogramSettings::defaults().LoadPrefs(); WaveformSettings::defaults().LoadPrefs(); - GlobalPrefsDialog dialog(&project /* parent */ ); + GlobalPrefsDialog dialog(&GetProjectFrame( project ) /* parent */ ); wxCommandEvent Evt; //dialog.Show(); dialog.OnOK(Evt); @@ -189,9 +191,10 @@ void DoReloadPreferences( AudacityProject &project ) // // This workaround should be removed when Audacity updates to wxWidgets // 3.x which has a fix. - wxRect r = p->GetRect(); - p->SetSize(wxSize(1,1)); - p->SetSize(r.GetSize()); + auto &window = GetProjectFrame( *p ); + wxRect r = window.GetRect(); + window.SetSize(wxSize(1,1)); + window.SetSize(r.GetSize()); #endif } } @@ -209,7 +212,7 @@ bool DoEditMetadata // BEFORE doing any editing of it! auto newTags = tags.Duplicate(); - if (newTags->ShowEditDialog(&project, title, force)) { + if (newTags->ShowEditDialog(&GetProjectFrame( project ), title, force)) { if (tags != *newTags) { // Commit the change to project state only now. Tags::Set( project, newTags ); @@ -228,6 +231,7 @@ void DoUndo(AudacityProject &project) { auto &trackPanel = TrackPanel::Get( project ); auto &undoManager = UndoManager::Get( project ); + auto &window = ProjectWindow::Get( project ); if (!project.UndoAvailable()) { AudacityMessageBox(_("Nothing to undo")); @@ -244,7 +248,7 @@ void DoUndo(AudacityProject &project) trackPanel.EnsureVisible(trackPanel.GetFirstSelectedTrack()); - project.RedrawProject(); + window.RedrawProject(); MenuManager::ModifyUndoMenuItems(project); } @@ -263,6 +267,7 @@ void OnRedo(const CommandContext &context) auto &project = context.project; auto &trackPanel = TrackPanel::Get( project ); auto &undoManager = UndoManager::Get( project ); + auto &window = ProjectWindow::Get( project ); if (!project.RedoAvailable()) { AudacityMessageBox(_("Nothing to redo")); @@ -278,7 +283,7 @@ void OnRedo(const CommandContext &context) trackPanel.EnsureVisible(trackPanel.GetFirstSelectedTrack()); - project.RedrawProject(); + window.RedrawProject(); MenuManager::ModifyUndoMenuItems(project); } @@ -290,6 +295,7 @@ void OnCut(const CommandContext &context) auto &trackPanel = TrackPanel::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; auto &ruler = AdornedRulerPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); // This doesn't handle cutting labels, it handles // cutting the _text_ inside of labels, i.e. if you're @@ -366,7 +372,7 @@ void OnCut(const CommandContext &context) //mRuler->ClearPlayRegion(); ruler.DrawOverlays( true ); - project.RedrawProject(); + window.RedrawProject(); } void OnDelete(const CommandContext &context) @@ -374,6 +380,7 @@ void OnDelete(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); for (auto n : tracks.Any()) { if (n->GetSelected() || n->IsSyncLockSelected()) { @@ -390,7 +397,7 @@ void OnDelete(const CommandContext &context) selectedRegion.t0()), _("Delete")); - project.RedrawProject(); + window.RedrawProject(); } @@ -435,6 +442,8 @@ void OnPaste(const CommandContext &context) auto &trackPanel = TrackPanel::Get( project ); auto &trackFactory = TrackFactory::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); + auto isSyncLocked = project.IsSyncLocked(); // Handle text paste (into active label) first. @@ -684,7 +693,7 @@ void OnPaste(const CommandContext &context) project.PushState(_("Pasted from the clipboard"), _("Paste")); - project.RedrawProject(); + window.RedrawProject(); if (ff) trackPanel.EnsureVisible(ff); @@ -696,6 +705,7 @@ void OnDuplicate(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); // This iteration is unusual because we add to the list inside the loop auto range = tracks.Selected(); @@ -715,7 +725,7 @@ void OnDuplicate(const CommandContext &context) project.PushState(_("Duplicated"), _("Duplicate")); - project.RedrawProject(); + window.RedrawProject(); } void OnSplitCut(const CommandContext &context) @@ -723,6 +733,7 @@ void OnSplitCut(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); auto &clipboard = Clipboard::Get(); clipboard.Clear(); @@ -756,7 +767,7 @@ void OnSplitCut(const CommandContext &context) project.PushState(_("Split-cut to the clipboard"), _("Split Cut")); - project.RedrawProject(); + window.RedrawProject(); } void OnSplitDelete(const CommandContext &context) @@ -764,6 +775,7 @@ void OnSplitDelete(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); tracks.Selected().Visit( [&](WaveTrack *wt) { @@ -782,7 +794,7 @@ void OnSplitDelete(const CommandContext &context) selectedRegion.t0()), _("Split Delete")); - project.RedrawProject(); + window.RedrawProject(); } void OnSilence(const CommandContext &context) @@ -809,6 +821,7 @@ void OnTrim(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); if (selectedRegion.isPoint()) return; @@ -833,7 +846,7 @@ void OnTrim(const CommandContext &context) selectedRegion.t0(), selectedRegion.t1()), _("Trim Audio")); - project.RedrawProject(); + window.RedrawProject(); } void OnSplit(const CommandContext &context) @@ -907,6 +920,7 @@ void OnSplitNew(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); Track::Holder dest; @@ -950,7 +964,7 @@ void OnSplitNew(const CommandContext &context) project.PushState(_("Split to new track"), _("Split New")); - project.RedrawProject(); + window.RedrawProject(); } void OnJoin(const CommandContext &context) @@ -958,6 +972,7 @@ void OnJoin(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); for (auto wt : tracks.Selected< WaveTrack >()) wt->Join(selectedRegion.t0(), @@ -969,7 +984,7 @@ void OnJoin(const CommandContext &context) selectedRegion.t0()), _("Join")); - project.RedrawProject(); + window.RedrawProject(); } void OnDisjoin(const CommandContext &context) @@ -977,6 +992,7 @@ void OnDisjoin(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); for (auto wt : tracks.Selected< WaveTrack >()) wt->Disjoin(selectedRegion.t0(), @@ -988,7 +1004,7 @@ void OnDisjoin(const CommandContext &context) selectedRegion.t0()), _("Detach")); - project.RedrawProject(); + window.RedrawProject(); } void OnEditMetadata(const CommandContext &context) @@ -1002,7 +1018,7 @@ void OnPreferences(const CommandContext &context) { auto &project = context.project; - GlobalPrefsDialog dialog(&project /* parent */ ); + GlobalPrefsDialog dialog(&GetProjectFrame( project ) /* parent */ ); if( ScreenshotCommand::MayCapture( &dialog ) ) return; @@ -1027,9 +1043,10 @@ void OnPreferences(const CommandContext &context) // // This workaround should be removed when Audacity updates to wxWidgets // 3.x which has a fix. - wxRect r = p->GetRect(); - p->SetSize(wxSize(1,1)); - p->SetSize(r.GetSize()); + auto &window = GetProjectFrame( *p ); + wxRect r = window.GetRect(); + window.SetSize(wxSize(1,1)); + window.SetSize(r.GetSize()); #endif } } diff --git a/src/menus/ExtraMenus.cpp b/src/menus/ExtraMenus.cpp index 3e2e2fd5f..c8d560fe8 100644 --- a/src/menus/ExtraMenus.cpp +++ b/src/menus/ExtraMenus.cpp @@ -110,10 +110,11 @@ void OnAudioHost(const CommandContext &context) void OnFullScreen(const CommandContext &context) { auto &project = context.project; + auto &window = GetProjectFrame( project ); auto &commandManager = CommandManager::Get( project ); - bool bChecked = !project.wxTopLevelWindow::IsFullScreen(); - project.wxTopLevelWindow::ShowFullScreen(bChecked); + bool bChecked = !window.wxTopLevelWindow::IsFullScreen(); + window.wxTopLevelWindow::ShowFullScreen(bChecked); commandManager.Check(wxT("FullScreenOnOff"), bChecked); } @@ -243,8 +244,8 @@ MenuTable::BaseItemPtr ExtraMiscItems( AudacityProject &project ) Command( wxT("FullScreenOnOff"), XXO("&Full Screen (on/off)"), FN(OnFullScreen), AlwaysEnabledFlag, - Options{ key } - .CheckState( project.wxTopLevelWindow::IsFullScreen() ) ), + Options{ key }.CheckState( + GetProjectFrame( project ).wxTopLevelWindow::IsFullScreen() ) ), ExtraWindowItems ); diff --git a/src/menus/FileMenus.cpp b/src/menus/FileMenus.cpp index 2890bd6d6..7cba59f65 100644 --- a/src/menus/FileMenus.cpp +++ b/src/menus/FileMenus.cpp @@ -118,7 +118,7 @@ AudacityProject *DoImportMIDI( if ( !pProject ) pProject = pNewProject = CreateNewAudacityProject(); auto cleanup = finally( [&] - { if ( pNewProject ) pNewProject->Close(true); } ); + { if ( pNewProject ) GetProjectFrame( *pNewProject ).Close(true); } ); auto newTrack = TrackFactory::Get( *pProject ).NewNoteTrack(); @@ -131,7 +131,7 @@ AudacityProject *DoImportMIDI( pProject->PushState(wxString::Format(_("Imported MIDI from '%s'"), fileName), _("Import MIDI")); - pProject->ZoomAfterImport(pTrack); + ProjectWindow::Get( *pProject ).ZoomAfterImport(pTrack); pNewProject = nullptr; FileHistory::Global().AddFileToHistory(fileName); @@ -174,8 +174,9 @@ void OnProjectReset(const CommandContext &context) void OnClose(const CommandContext &context ) { auto &project = context.project; + auto &window = GetProjectFrame( project ); project.SetMenuClose(true); - project.Close(); + window.Close(); } void OnSave(const CommandContext &context ) @@ -244,6 +245,7 @@ void OnExportLabels(const CommandContext &context) { auto &project = context.project; auto &tracks = TrackList::Get( project ); + auto &window = GetProjectFrame( project ); /* i18n-hint: filename containing exported text from label tracks */ wxString fName = _("labels.txt"); @@ -264,7 +266,7 @@ void OnExportLabels(const CommandContext &context) wxT("txt"), wxT("*.txt"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER, - &project); + &window); if (fName.empty()) return; @@ -315,6 +317,7 @@ void OnExportMIDI(const CommandContext &context) { auto &project = context.project; auto &tracks = TrackList::Get( project ); + auto &window = GetProjectFrame( project ); // Make sure that there is // exactly one NoteTrack selected. @@ -349,7 +352,7 @@ void OnExportMIDI(const CommandContext &context) wxT(".mid|.gro"), _("MIDI file (*.mid)|*.mid|Allegro file (*.gro)|*.gro"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER, - &project); + &window); if (fName.empty()) return; @@ -396,6 +399,7 @@ void OnExportMIDI(const CommandContext &context) void OnImport(const CommandContext &context) { auto &project = context.project; + auto &window = ProjectWindow::Get( project ); // An import trigger for the alias missing dialog might not be intuitive, but // this serves to track the file if the users zooms in and such. @@ -423,7 +427,7 @@ void OnImport(const CommandContext &context) gPrefs->Flush(); - project.HandleResize(); // Adjust scrollers for NEW track sizes. + window.HandleResize(); // Adjust scrollers for NEW track sizes. } ); for (size_t ff = 0; ff < selectedFiles.size(); ff++) { @@ -434,7 +438,7 @@ void OnImport(const CommandContext &context) project.Import(fileName); } - project.ZoomAfterImport(nullptr); + window.ZoomAfterImport(nullptr); } void OnImportLabels(const CommandContext &context) @@ -442,6 +446,7 @@ void OnImportLabels(const CommandContext &context) auto &project = context.project; auto &trackFactory = TrackFactory::Get( project ); auto &tracks = TrackList::Get( project ); + auto &window = ProjectWindow::Get( project ); wxString fileName = FileNames::SelectFile(FileNames::Operation::Open, @@ -451,7 +456,7 @@ void OnImportLabels(const CommandContext &context) wxT(".txt"), // Extension _("Text files (*.txt)|*.txt|All files|*"), wxRESIZE_BORDER, // Flags - &project); // Parent + &window); // Parent if (!fileName.empty()) { wxTextFile f; @@ -478,13 +483,14 @@ void OnImportLabels(const CommandContext &context) Format(_("Imported labels from '%s'"), fileName), _("Import Labels")); - project.ZoomAfterImport(nullptr); + window.ZoomAfterImport(nullptr); } } void OnImportMIDI(const CommandContext &context) { auto &project = context.project; + auto &window = GetProjectFrame( project ); wxString fileName = FileNames::SelectFile(FileNames::Operation::Open, _("Select a MIDI file"), @@ -493,7 +499,7 @@ void OnImportMIDI(const CommandContext &context) wxT(""), // Extension _("MIDI and Allegro files (*.mid;*.midi;*.gro)|*.mid;*.midi;*.gro|MIDI files (*.mid;*.midi)|*.mid;*.midi|Allegro files (*.gro)|*.gro|All files|*"), wxRESIZE_BORDER, // Flags - &project); // Parent + &window); // Parent if (!fileName.empty()) DoImportMIDI(&project, fileName); @@ -504,6 +510,7 @@ void OnImportRaw(const CommandContext &context) { auto &project = context.project; auto &trackFactory = TrackFactory::Get( project ); + auto &window = ProjectWindow::Get( project ); wxString fileName = FileNames::SelectFile(FileNames::Operation::Open, @@ -513,26 +520,27 @@ void OnImportRaw(const CommandContext &context) wxT(""), // Extension _("All files|*"), wxRESIZE_BORDER, // Flags - &project); // Parent + &window); // Parent if (fileName.empty()) return; TrackHolders newTracks; - ::ImportRaw(&project, fileName, &trackFactory, newTracks); + ::ImportRaw(&window, fileName, &trackFactory, newTracks); if (newTracks.size() <= 0) return; project.AddImportedTracks(fileName, std::move(newTracks)); - project.HandleResize(); // Adjust scrollers for NEW track sizes. + window.HandleResize(); // Adjust scrollers for NEW track sizes. } void OnPageSetup(const CommandContext &context) { auto &project = context.project; - HandlePageSetup(&project); + auto &window = GetProjectFrame( project ); + HandlePageSetup(&window); } void OnPrint(const CommandContext &context) @@ -540,7 +548,8 @@ void OnPrint(const CommandContext &context) auto &project = context.project; auto name = project.GetProjectName(); auto &tracks = TrackList::Get( project ); - HandlePrint(&project, name, &tracks, TrackPanel::Get( project )); + auto &window = GetProjectFrame( project ); + HandlePrint(&window, name, &tracks, TrackPanel::Get( project )); } void OnExit(const CommandContext &WXUNUSED(context) ) diff --git a/src/menus/HelpMenus.cpp b/src/menus/HelpMenus.cpp index 2c34ea5d3..b25698f9e 100644 --- a/src/menus/HelpMenus.cpp +++ b/src/menus/HelpMenus.cpp @@ -35,7 +35,8 @@ void ShowDiagnostics( AudacityProject &project, const wxString &info, const wxString &description, const wxString &defaultPath) { - wxDialogWrapper dlg(&project, wxID_ANY, description); + auto &window = GetProjectFrame( project ); + wxDialogWrapper dlg( &window, wxID_ANY, description); dlg.SetName(dlg.GetTitle()); ShuttleGui S(&dlg, eIsCreating); @@ -62,7 +63,7 @@ void ShowDiagnostics( wxT("txt"), wxT("*.txt"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER, - &project); + &window); if (!fName.empty()) { if (!text->SaveFile(fName)) @@ -280,7 +281,7 @@ namespace HelpActions { void DoHelpWelcome( AudacityProject &project ) { - SplashDialog::Show2( &project ); + SplashDialog::Show2( &GetProjectFrame( project ) ); } // Menu handler functions @@ -290,7 +291,7 @@ struct Handler : CommandHandlerObject { void OnQuickFix(const CommandContext &context) { auto &project = context.project; - QuickFixDialog dlg( &project ); + QuickFixDialog dlg( &GetProjectFrame( project ) ); dlg.ShowModal(); } @@ -298,7 +299,7 @@ void OnQuickHelp(const CommandContext &context) { auto &project = context.project; HelpSystem::ShowHelp( - &project, + &GetProjectFrame( project ), wxT("Quick_Help")); } @@ -306,7 +307,7 @@ void OnManual(const CommandContext &context) { auto &project = context.project; HelpSystem::ShowHelp( - &project, + &GetProjectFrame( project ), wxT("Main_Page")); } @@ -368,9 +369,10 @@ void OnAbout(const CommandContext &context) wxTheApp->AddPendingEvent( evt ); #else auto &project = context.project; + auto &window = GetProjectFrame( project ); // Windows and Linux still modal. - AboutDialog dlog(&project); + AboutDialog dlog( &window ); dlog.ShowModal(); #endif } diff --git a/src/menus/LabelMenus.cpp b/src/menus/LabelMenus.cpp index 8b8a08d66..89802a341 100644 --- a/src/menus/LabelMenus.cpp +++ b/src/menus/LabelMenus.cpp @@ -21,6 +21,7 @@ int DoAddLabel( auto &tracks = TrackList::Get( project ); auto &trackPanel = TrackPanel::Get( project ); auto &trackFactory = TrackFactory::Get( project ); + auto &window = ProjectWindow::Get( project ); wxString title; // of label @@ -71,7 +72,7 @@ int DoAddLabel( project.PushState(_("Added label"), _("Label")); - project.RedrawProject(); + window.RedrawProject(); if (!useDialog) { trackPanel.EnsureVisible(lt); } @@ -284,6 +285,7 @@ void OnPasteNewLabel(const CommandContext &context) auto &trackFactory = TrackFactory::Get( project ); auto &trackPanel = TrackPanel::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); bool bPastedSomething = false; @@ -337,7 +339,7 @@ void OnPasteNewLabel(const CommandContext &context) _("Pasted from the clipboard"), _("Paste Text to New Label")); // Is this necessary? (carried over from former logic in OnPaste()) - project.RedrawProject(); + window.RedrawProject(); } } @@ -355,6 +357,7 @@ void OnCutLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; @@ -379,7 +382,7 @@ void OnCutLabels(const CommandContext &context) /* i18n-hint: (verb)*/ _( "Cut Labeled Audio" ) ); - project.RedrawProject(); + window.RedrawProject(); } void OnDeleteLabels(const CommandContext &context) @@ -387,6 +390,7 @@ void OnDeleteLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; @@ -401,7 +405,7 @@ void OnDeleteLabels(const CommandContext &context) /* i18n-hint: (verb)*/ _( "Delete Labeled Audio" ) ); - project.RedrawProject(); + window.RedrawProject(); } void OnSplitCutLabels(const CommandContext &context) @@ -409,6 +413,7 @@ void OnSplitCutLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; @@ -423,7 +428,7 @@ void OnSplitCutLabels(const CommandContext &context) /* i18n-hint: (verb) Do a special kind of cut on the labels*/ _( "Split Cut Labeled Audio" ) ); - project.RedrawProject(); + window.RedrawProject(); } void OnSplitDeleteLabels(const CommandContext &context) @@ -431,6 +436,7 @@ void OnSplitDeleteLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; @@ -445,7 +451,7 @@ void OnSplitDeleteLabels(const CommandContext &context) regions */ _( "Split Delete Labeled Audio" ) ); - project.RedrawProject(); + window.RedrawProject(); } void OnSilenceLabels(const CommandContext &context) @@ -494,6 +500,7 @@ void OnSplitLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); EditByLabel( tracks, selectedRegion, &WaveTrack::Split, false ); @@ -504,7 +511,7 @@ void OnSplitLabels(const CommandContext &context) /* i18n-hint: (verb)*/ _( "Split Labeled Audio" ) ); - project.RedrawProject(); + window.RedrawProject(); } void OnJoinLabels(const CommandContext &context) @@ -512,6 +519,7 @@ void OnJoinLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; @@ -525,7 +533,7 @@ void OnJoinLabels(const CommandContext &context) /* i18n-hint: (verb) */ _( "Join Labeled Audio" ) ); - project.RedrawProject(); + window.RedrawProject(); } void OnDisjoinLabels(const CommandContext &context) @@ -533,6 +541,7 @@ void OnDisjoinLabels(const CommandContext &context) auto &project = context.project; auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); if( selectedRegion.isPoint() ) return; @@ -547,7 +556,7 @@ void OnDisjoinLabels(const CommandContext &context) /* i18n-hint: (verb)*/ _( "Detach Labeled Audio" ) ); - project.RedrawProject(); + window.RedrawProject(); } }; // struct Handler diff --git a/src/menus/NavigationMenus.cpp b/src/menus/NavigationMenus.cpp index caeaf2dd3..c1eaa41f9 100644 --- a/src/menus/NavigationMenus.cpp +++ b/src/menus/NavigationMenus.cpp @@ -35,7 +35,7 @@ void NextOrPrevFrame(AudacityProject &project, bool forward) static const unsigned rotationSize = 3u; wxWindow *const begin [rotationSize] = { - project.GetTopPanel(), + ProjectWindow::Get( project ).GetTopPanel(), &TrackPanel::Get( project ), botDock, }; @@ -310,15 +310,16 @@ struct Handler void OnPrevWindow(const CommandContext &context) { auto &project = context.project; - auto isEnabled = project.IsEnabled(); + auto &window = GetProjectFrame( project ); + auto isEnabled = window.IsEnabled(); wxWindow *w = wxGetTopLevelParent(wxWindow::FindFocus()); - const auto & list = project.GetChildren(); + const auto & list = window.GetChildren(); auto iter = list.rbegin(), end = list.rend(); // If the project window has the current focus, start the search with the // last child - if (w == &project) + if (w == &window) { } // Otherwise start the search with the current window's previous sibling @@ -345,7 +346,7 @@ void OnPrevWindow(const CommandContext &context) // Ran out of siblings, so make the current project active if ((iter == end) && isEnabled) { - w = &project; + w = &window; } // And make sure it's on top (only for floating windows...project window will @@ -368,15 +369,16 @@ void OnPrevWindow(const CommandContext &context) void OnNextWindow(const CommandContext &context) { auto &project = context.project; - auto isEnabled = project.IsEnabled(); + auto &window = GetProjectFrame( project ); + auto isEnabled = window.IsEnabled(); wxWindow *w = wxGetTopLevelParent(wxWindow::FindFocus()); - const auto & list = project.GetChildren(); + const auto & list = window.GetChildren(); auto iter = list.begin(), end = list.end(); // If the project window has the current focus, start the search with the // first child - if (w == &project) + if (w == &window) { } // Otherwise start the search with the current window's next sibling @@ -407,7 +409,7 @@ void OnNextWindow(const CommandContext &context) // Ran out of siblings, so make the current project active if ((iter == end) && isEnabled) { - w = &project; + w = &window; } // And make sure it's on top (only for floating windows...project window will diff --git a/src/menus/PluginMenus.cpp b/src/menus/PluginMenus.cpp index 913ffcefc..605bf1e53 100644 --- a/src/menus/PluginMenus.cpp +++ b/src/menus/PluginMenus.cpp @@ -25,8 +25,9 @@ namespace { AudacityProject::AttachedWindows::RegisteredFactory sContrastDialogKey{ []( AudacityProject &parent ) -> wxWeakRef< wxWindow > { + auto &window = ProjectWindow::Get( parent ); return safenew ContrastDialog( - &parent, -1, _("Contrast Analysis (WCAG 2 compliance)"), + &window, -1, _("Contrast Analysis (WCAG 2 compliance)"), wxPoint{ 150, 150 } ); } @@ -34,8 +35,9 @@ AudacityProject::AttachedWindows::RegisteredFactory sContrastDialogKey{ AudacityProject::AttachedWindows::RegisteredFactory sFrequencyWindowKey{ []( AudacityProject &parent ) -> wxWeakRef< wxWindow > { + auto &window = ProjectWindow::Get( parent ); return safenew FreqWindow( - &parent, -1, _("Frequency Analysis"), + &window, -1, _("Frequency Analysis"), wxPoint{ 150, 150 } ); } @@ -43,16 +45,17 @@ AudacityProject::AttachedWindows::RegisteredFactory sFrequencyWindowKey{ AudacityProject::AttachedWindows::RegisteredFactory sMacrosWindowKey{ []( AudacityProject &parent ) -> wxWeakRef< wxWindow > { + auto &window = ProjectWindow::Get( parent ); return safenew MacrosWindow( - &parent, true + &window, true ); } }; -void DoManagePluginsMenu -(AudacityProject &project, EffectType type) +void DoManagePluginsMenu(AudacityProject &project, EffectType type) { - if (PluginManager::Get().ShowManager(&project, type)) + auto &window = GetProjectFrame( project ); + if (PluginManager::Get().ShowManager(&window, type)) MenuCreator::RebuildAllMenuBars(); } @@ -426,6 +429,7 @@ bool DoEffect( auto rate = project.GetRate(); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; auto &commandManager = CommandManager::Get( project ); + auto &window = ProjectWindow::Get( project ); const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID); if (!plug) @@ -473,7 +477,7 @@ bool DoEffect( EffectManager & em = EffectManager::Get(); - success = em.DoEffect(ID, &project, rate, + success = em.DoEffect(ID, &window, rate, &tracks, &trackFactory, &selectedRegion, (flags & kConfigured) == 0); @@ -515,7 +519,7 @@ bool DoEffect( ViewActions::DoZoomFit(project); // trackPanel->Refresh(false); } - project.RedrawProject(); + window.RedrawProject(); if (focus != nullptr && focus->GetParent()==parent) { focus->SetFocus(); } @@ -543,6 +547,7 @@ bool DoAudacityCommand( const PluginID & ID, const CommandContext & context, unsigned flags ) { auto &project = context.project; + auto &window = ProjectWindow::Get( project ); const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID); if (!plug) return false; @@ -556,7 +561,7 @@ bool DoAudacityCommand( EffectManager & em = EffectManager::Get(); bool success = em.DoAudacityCommand(ID, context, - &project, + &window, (flags & kConfigured) == 0); if (!success) @@ -573,7 +578,7 @@ bool DoAudacityCommand( PushState(longDesc, shortDesc); } */ - project.RedrawProject(); + window.RedrawProject(); return true; } @@ -677,7 +682,8 @@ void OnScreenshot(const CommandContext &WXUNUSED(context) ) void OnBenchmark(const CommandContext &context) { auto &project = context.project; - ::RunBenchmark(&project); + auto &window = GetProjectFrame( project ); + ::RunBenchmark(&window); } void OnSimulateRecordingErrors(const CommandContext &context) @@ -703,9 +709,10 @@ void OnDetectUpstreamDropouts(const CommandContext &context) void OnApplyMacroDirectly(const CommandContext &context ) { auto &project = context.project; + auto &window = ProjectWindow::Get( project ); //wxLogDebug( "Macro was: %s", context.parameter); - ApplyMacroDialog dlg( &project ); + ApplyMacroDialog dlg( &window ); const auto &Name = context.parameter; // We used numbers previously, but macros could get renumbered, making diff --git a/src/menus/SelectMenus.cpp b/src/menus/SelectMenus.cpp index e4cdf02b2..acadc8255 100644 --- a/src/menus/SelectMenus.cpp +++ b/src/menus/SelectMenus.cpp @@ -271,6 +271,7 @@ void MoveWhenAudioInactive auto &trackPanel = TrackPanel::Get( project ); auto &tracks = TrackList::Get( project ); auto &ruler = AdornedRulerPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); // If TIME_UNIT_SECONDS, snap-to will be off. int snapToTime = project.GetSnapTo(); @@ -300,7 +301,7 @@ void MoveWhenAudioInactive // This updates the selection shown on the selection bar, and the play // region - project.TP_DisplaySelection(); + window.TP_DisplaySelection(); } else { // Transition to cursor mode. @@ -513,15 +514,16 @@ void DoListSelection auto &trackPanel = TrackPanel::Get( project ); auto &selectionState = SelectionState::Get( project ); auto &viewInfo = ViewInfo::Get( project ); - auto isSyncLocked = project.IsSyncLocked(); + auto &window = GetProjectFrame( project ); + auto isSyncLocked = project.IsSyncLocked(); selectionState.HandleListSelection( tracks, viewInfo, *t, shift, ctrl, isSyncLocked ); if (! ctrl ) trackPanel.SetFocusedTrack(t); - project.Refresh(false); + window.Refresh(false); if (modifyState) project.ModifyState(true); } @@ -610,6 +612,7 @@ void OnSetLeftSelection(const CommandContext &context) auto token = project.GetAudioIOToken(); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; auto &trackPanel = TrackPanel::Get( project ); + auto &window = GetProjectFrame( project ); bool bSelChanged = false; if ((token > 0) && gAudioIO->IsStreamActive(token)) @@ -623,7 +626,7 @@ void OnSetLeftSelection(const CommandContext &context) auto fmt = project.GetSelectionFormat(); auto rate = project.GetRate(); - TimeDialog dlg(&project, _("Set Left Selection Boundary"), + TimeDialog dlg(&window, _("Set Left Selection Boundary"), fmt, rate, selectedRegion.t0(), _("Position")); if (wxID_OK == dlg.ShowModal()) @@ -648,6 +651,7 @@ void OnSetRightSelection(const CommandContext &context) auto token = project.GetAudioIOToken(); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; auto &trackPanel = TrackPanel::Get( project ); + auto &window = GetProjectFrame( project ); bool bSelChanged = false; if ((token > 0) && gAudioIO->IsStreamActive(token)) @@ -661,7 +665,7 @@ void OnSetRightSelection(const CommandContext &context) auto fmt = project.GetSelectionFormat(); auto rate = project.GetRate(); - TimeDialog dlg(&project, _("Set Right Selection Boundary"), + TimeDialog dlg(&window, _("Set Right Selection Boundary"), fmt, rate, selectedRegion.t1(), _("Position")); if (wxID_OK == dlg.ShowModal()) @@ -901,14 +905,16 @@ void OnSnapToPrior(const CommandContext &context) void OnSelToStart(const CommandContext &context) { auto &project = context.project; - project.Rewind(true); + auto &window = ProjectWindow::Get( project ); + window.Rewind(true); project.ModifyState(false); } void OnSelToEnd(const CommandContext &context) { auto &project = context.project; - project.SkipEnd(true); + auto &window = ProjectWindow::Get( project ); + window.SkipEnd(true); project.ModifyState(false); } diff --git a/src/menus/TrackMenus.cpp b/src/menus/TrackMenus.cpp index 2df726ccd..e3d7432f7 100644 --- a/src/menus/TrackMenus.cpp +++ b/src/menus/TrackMenus.cpp @@ -43,6 +43,7 @@ void DoMixAndRender auto rate = project.GetRate(); auto defaultFormat = project.GetDefaultFormat(); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); MissingAliasFilesDialog::SetShouldShow(true); @@ -105,13 +106,14 @@ void DoMixAndRender trackPanel.SetFocus(); trackPanel.SetFocusedTrack(pNewLeft); trackPanel.EnsureVisible(pNewLeft); - project.RedrawProject(); + window.RedrawProject(); } } void DoPanTracks(AudacityProject &project, float PanValue) { auto &tracks = TrackList::Get( project ); + auto &window = ProjectWindow::Get( project ); // count selected wave tracks const auto range = tracks.Any< WaveTrack >(); @@ -122,7 +124,7 @@ void DoPanTracks(AudacityProject &project, float PanValue) for (auto left : count == 0 ? range : selectedRange ) left->SetPan( PanValue ); - project.RedrawProject(); + window.RedrawProject(); auto flags = UndoPush::AUTOSAVE; /*i18n-hint: One or more audio tracks have been panned*/ @@ -156,6 +158,7 @@ void DoAlign { auto &tracks = TrackList::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); wxString action; wxString shortAction; @@ -288,7 +291,7 @@ void DoAlign project.PushState(action, shortAction); - project.RedrawProject(); + window.RedrawProject(); } #ifdef EXPERIMENTAL_SCOREALIGN @@ -700,6 +703,7 @@ void DoRemoveTrack(AudacityProject &project, Track * toRemove) { auto &tracks = TrackList::Get( project ); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); // If it was focused, then NEW focus is the next or, if // unavailable, the previous track. (The NEW focus is set @@ -730,8 +734,8 @@ void DoRemoveTrack(AudacityProject &project, Track * toRemove) name), _("Track Remove")); - project.FixScrollbars(); - project.HandleResize(); + window.FixScrollbars(); + window.HandleResize(); trackPanel.Refresh(false); } @@ -798,6 +802,8 @@ void OnNewWaveTrack(const CommandContext &context) auto &tracks = TrackList::Get( project ); auto &trackFactory = TrackFactory::Get( project ); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); + auto defaultFormat = project.GetDefaultFormat(); auto rate = project.GetRate(); @@ -808,7 +814,7 @@ void OnNewWaveTrack(const CommandContext &context) project.PushState(_("Created new audio track"), _("New Track")); - project.RedrawProject(); + window.RedrawProject(); trackPanel.EnsureVisible(t); } @@ -818,6 +824,8 @@ void OnNewStereoTrack(const CommandContext &context) auto &tracks = TrackList::Get( project ); auto &trackFactory = TrackFactory::Get( project ); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); + auto defaultFormat = project.GetDefaultFormat(); auto rate = project.GetRate(); @@ -833,7 +841,7 @@ void OnNewStereoTrack(const CommandContext &context) project.PushState(_("Created new stereo audio track"), _("New Track")); - project.RedrawProject(); + window.RedrawProject(); trackPanel.EnsureVisible(left); } @@ -843,6 +851,7 @@ void OnNewLabelTrack(const CommandContext &context) auto &tracks = TrackList::Get( project ); auto &trackFactory = TrackFactory::Get( project ); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); auto t = tracks.Add( trackFactory.NewLabelTrack() ); @@ -852,7 +861,7 @@ void OnNewLabelTrack(const CommandContext &context) project.PushState(_("Created new label track"), _("New Track")); - project.RedrawProject(); + window.RedrawProject(); trackPanel.EnsureVisible(t); } @@ -862,6 +871,7 @@ void OnNewTimeTrack(const CommandContext &context) auto &tracks = TrackList::Get( project ); auto &trackFactory = TrackFactory::Get( project ); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); if (tracks.GetTimeTrack()) { AudacityMessageBox(_("This version of Audacity only allows one time track for each project window.")); @@ -876,7 +886,7 @@ void OnNewTimeTrack(const CommandContext &context) project.PushState(_("Created new time track"), _("New Track")); - project.RedrawProject(); + window.RedrawProject(); trackPanel.EnsureVisible(t); } @@ -906,12 +916,13 @@ void OnResample(const CommandContext &context) auto projectRate = project.GetRate(); auto &tracks = TrackList::Get( project ); auto &undoManager = UndoManager::Get( project ); + auto &window = ProjectWindow::Get( project ); int newRate; while (true) { - wxDialogWrapper dlg(&project, wxID_ANY, wxString(_("Resample"))); + wxDialogWrapper dlg(&window, wxID_ANY, wxString(_("Resample"))); dlg.SetName(dlg.GetTitle()); ShuttleGui S(&dlg, eIsCreating); wxString rate; @@ -970,7 +981,7 @@ void OnResample(const CommandContext &context) } AudacityMessageBox(_("The entered value is invalid"), _("Error"), - wxICON_ERROR, &project); + wxICON_ERROR, &window); } int ndx = 0; @@ -1000,10 +1011,10 @@ void OnResample(const CommandContext &context) } undoManager.StopConsolidating(); - project.RedrawProject(); + window.RedrawProject(); // Need to reset - project.FinishAutoScroll(); + window.FinishAutoScroll(); } void OnRemoveTracks(const CommandContext &context) @@ -1015,6 +1026,8 @@ void OnMuteAllTracks(const CommandContext &context) { auto &project = context.project; auto &tracks = TrackList::Get( project ); + auto &window = ProjectWindow::Get( project ); + auto soloSimple = project.IsSoloSimple(); auto soloNone = project.IsSoloNone(); @@ -1026,13 +1039,15 @@ void OnMuteAllTracks(const CommandContext &context) } project.ModifyState(true); - project.RedrawProject(); + window.RedrawProject(); } void OnUnmuteAllTracks(const CommandContext &context) { auto &project = context.project; auto &tracks = TrackList::Get( project ); + auto &window = ProjectWindow::Get( project ); + auto soloSimple = project.IsSoloSimple(); auto soloNone = project.IsSoloNone(); @@ -1044,7 +1059,7 @@ void OnUnmuteAllTracks(const CommandContext &context) } project.ModifyState(true); - project.RedrawProject(); + window.RedrawProject(); } void OnPanLeft(const CommandContext &context) diff --git a/src/menus/TransportMenus.cpp b/src/menus/TransportMenus.cpp index 3a8f0c8ca..f37b711cc 100644 --- a/src/menus/TransportMenus.cpp +++ b/src/menus/TransportMenus.cpp @@ -80,6 +80,7 @@ void DoPlayStop(const CommandContext &context) { auto &project = context.project; auto &toolbar = ControlToolBar::Get( project ); + auto &window = ProjectWindow::Get( project ); auto token = project.GetAudioIOToken(); //If this project is playing, stop playing, make sure everything is unpaused. @@ -112,7 +113,7 @@ void DoPlayStop(const CommandContext &context) //play the front project if (!gAudioIO->IsBusy()) { //update the playing area - project.TP_DisplaySelection(); + window.TP_DisplaySelection(); //Otherwise, start playing (assuming audio I/O isn't busy) //toolbar->SetPlay(true); // Not needed as done in PlayPlayRegion. toolbar.SetStop(false); @@ -135,6 +136,7 @@ void DoMoveToLabel(AudacityProject &project, bool next) { auto &tracks = TrackList::Get( project ); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); // Find the number of label tracks, and ptr to last track found auto trackRange = tracks.Any(); @@ -168,13 +170,13 @@ void DoMoveToLabel(AudacityProject &project, bool next) if (project.IsAudioActive()) { DoPlayStop(project); // stop selectedRegion = label->selectedRegion; - project.RedrawProject(); + window.RedrawProject(); DoPlayStop(project); // play } else { selectedRegion = label->selectedRegion; trackPanel.ScrollIntoView(selectedRegion.t0()); - project.RedrawProject(); + window.RedrawProject(); } wxString message; @@ -400,6 +402,7 @@ void OnTimerRecord(const CommandContext &context) { auto &project = context.project; auto &undoManager = UndoManager::Get( project ); + auto &window = ProjectWindow::Get( project ); // MY: Due to improvements in how Timer Recording saves and/or exports // it is now safer to disable Timer Recording when there is more than @@ -431,7 +434,7 @@ void OnTimerRecord(const CommandContext &context) //and therefore remove the newly inserted track. TimerRecordDialog dialog( - &project, bProjectSaved); /* parent, project saved? */ + &window, bProjectSaved); /* parent, project saved? */ int modalResult = dialog.ShowModal(); if (modalResult == wxID_CANCEL) { @@ -443,9 +446,9 @@ void OnTimerRecord(const CommandContext &context) bool bPreferNewTrack; gPrefs->Read("/GUI/PreferNewTrackRecord",&bPreferNewTrack, false); if (bPreferNewTrack) { - project.Rewind(false); + window.Rewind(false); } else { - project.SkipEnd(false); + window.SkipEnd(false); } int iTimerRecordingOutcome = dialog.RunWaitDialog(); @@ -494,6 +497,7 @@ void OnPunchAndRoll(const CommandContext &context) { AudacityProject &project = context.project; auto &viewInfo = ViewInfo::Get( project ); + auto &window = GetProjectFrame( project ); static const auto url = wxT("Punch_and_Roll_Record#Using_Punch_and_Roll_Record"); @@ -518,7 +522,7 @@ void OnPunchAndRoll(const CommandContext &context) ? _("Please select in a stereo track.") : wxString::Format( _("Please select at least %d channels."), recordingChannels); - ShowErrorDialog(&project, _("Error"), message, url); + ShowErrorDialog(&window, _("Error"), message, url); return; } @@ -560,7 +564,7 @@ void OnPunchAndRoll(const CommandContext &context) if (error) { auto message = _("Please select a time within a clip."); - ShowErrorDialog(&project, _("Error"), message, url); + ShowErrorDialog( &window, _("Error"), message, url); return; } @@ -639,7 +643,7 @@ void OnSoundActivated(const CommandContext &context) { AudacityProject &project = context.project; - SoundActivatedRecord dialog(&project /* parent */ ); + SoundActivatedRecord dialog( &GetProjectFrame( project ) /* parent */ ); dialog.ShowModal(); } diff --git a/src/menus/ViewMenus.cpp b/src/menus/ViewMenus.cpp index 51448664c..7740bfa61 100644 --- a/src/menus/ViewMenus.cpp +++ b/src/menus/ViewMenus.cpp @@ -47,10 +47,11 @@ double GetZoomOfSelection( const AudacityProject &project ) { auto &viewInfo = ViewInfo::Get( project ); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); const double lowerBound = std::max(viewInfo.selectedRegion.t0(), - project.ScrollingLowerBoundTime()); + window.ScrollingLowerBoundTime()); const double denom = viewInfo.selectedRegion.t1() - lowerBound; if (denom <= 0.0) @@ -165,13 +166,14 @@ void DoZoomFit(AudacityProject &project) { auto &viewInfo = ViewInfo::Get( project ); auto &tracks = TrackList::Get( project ); + auto &window = ProjectWindow::Get( project ); const double start = viewInfo.bScrollBeyondZero ? std::min(tracks.GetStartTime(), 0.0) : 0; - project.Zoom( GetZoomOfToFit( project ) ); - project.TP_ScrollWindow(start); + window.Zoom( GetZoomOfToFit( project ) ); + window.TP_ScrollWindow(start); } void DoZoomFitV(AudacityProject &project) @@ -209,31 +211,35 @@ struct Handler : CommandHandlerObject { void OnZoomIn(const CommandContext &context) { auto &project = context.project; - project.ZoomInByFactor( 2.0 ); + auto &window = ProjectWindow::Get( project ); + window.ZoomInByFactor( 2.0 ); } void OnZoomNormal(const CommandContext &context) { auto &project = context.project; auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); - project.Zoom(ZoomInfo::GetDefaultZoom()); + window.Zoom(ZoomInfo::GetDefaultZoom()); trackPanel.Refresh(false); } void OnZoomOut(const CommandContext &context) { auto &project = context.project; - project.ZoomOutByFactor( 1 /2.0 ); + auto &window = ProjectWindow::Get( project ); + window.ZoomOutByFactor( 1 /2.0 ); } void OnZoomSel(const CommandContext &context) { auto &project = context.project; auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; + auto &window = ProjectWindow::Get( project ); - project.Zoom( GetZoomOfSelection( project ) ); - project.TP_ScrollWindow(selectedRegion.t0()); + window.Zoom( GetZoomOfSelection( project ) ); + window.TP_ScrollWindow(selectedRegion.t0()); } void OnZoomToggle(const CommandContext &context) @@ -241,6 +247,7 @@ void OnZoomToggle(const CommandContext &context) auto &project = context.project; auto &viewInfo = ViewInfo::Get( project ); auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); // const double origLeft = viewInfo.h; // const double origWidth = GetScreenEndTime() - origLeft; @@ -252,7 +259,7 @@ void OnZoomToggle(const CommandContext &context) double ChosenZoom = fabs(log(Zoom1 / Z)) > fabs(log( Z / Zoom2)) ? Zoom1:Zoom2; - project.Zoom(ChosenZoom); + window.Zoom(ChosenZoom); trackPanel.Refresh(false); // const double newWidth = GetScreenEndTime() - viewInfo.h; // const double newh = origLeft + (origWidth - newWidth) / 2; @@ -267,11 +274,12 @@ void OnZoomFit(const CommandContext &context) void OnZoomFitV(const CommandContext &context) { auto &project = context.project; + auto &window = ProjectWindow::Get( project ); DoZoomFitV(project); - project.GetVerticalScrollBar().SetThumbPosition(0); - project.RedrawProject(); + window.GetVerticalScrollBar().SetThumbPosition(0); + window.RedrawProject(); project.ModifyState(true); } @@ -291,24 +299,26 @@ void OnCollapseAllTracks(const CommandContext &context) { auto &project = context.project; auto &tracks = TrackList::Get( project ); + auto &window = ProjectWindow::Get( project ); for (auto t : tracks.Any()) t->SetMinimized(true); project.ModifyState(true); - project.RedrawProject(); + window.RedrawProject(); } void OnExpandAllTracks(const CommandContext &context) { auto &project = context.project; auto &tracks = TrackList::Get( project ); + auto &window = ProjectWindow::Get( project ); for (auto t : tracks.Any()) t->SetMinimized(false); project.ModifyState(true); - project.RedrawProject(); + window.RedrawProject(); } void OnGoSelStart(const CommandContext &context) @@ -317,11 +327,12 @@ void OnGoSelStart(const CommandContext &context) auto &viewInfo = ViewInfo::Get( project ); auto &selectedRegion = viewInfo.selectedRegion; auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); if (selectedRegion.isPoint()) return; - project.TP_ScrollWindow( + window.TP_ScrollWindow( selectedRegion.t0() - ((trackPanel.GetScreenEndTime() - viewInfo.h) / 2)); } @@ -331,11 +342,12 @@ void OnGoSelEnd(const CommandContext &context) auto &viewInfo = ViewInfo::Get( project ); auto &selectedRegion = viewInfo.selectedRegion; auto &trackPanel = TrackPanel::Get( project ); + auto &window = ProjectWindow::Get( project ); if (selectedRegion.isPoint()) return; - project.TP_ScrollWindow( + window.TP_ScrollWindow( selectedRegion.t1() - ((trackPanel.GetScreenEndTime() - viewInfo.h) / 2)); } diff --git a/src/menus/WindowMenus.cpp b/src/menus/WindowMenus.cpp index 79d36870e..4b4be7356 100644 --- a/src/menus/WindowMenus.cpp +++ b/src/menus/WindowMenus.cpp @@ -28,8 +28,8 @@ namespace { void DoMacMinimize(AudacityProject *project) { - auto window = project; - if (window) { + if (project) { + auto window = &GetProjectFrame( *project ); #ifdef USE_COCOA // Adapted from mbarman.mm in wxWidgets 3.0.2 auto peer = window->GetPeer(); @@ -67,7 +67,7 @@ void OnMacMinimize(const CommandContext &context) void OnMacZoom(const CommandContext &context) { - auto window = &context.project; + auto window = &GetProjectFrame( context.project ); auto topWindow = static_cast(window); auto maximized = topWindow->IsMaximized(); if (window) { @@ -89,9 +89,8 @@ void OnMacBringAllToFront(const CommandContext &) { // Reall this de-miniaturizes all, which is not exactly the standard // behavior. - for (const auto project : gAudacityProjects) { - project->Raise(); - } + for (const auto project : gAudacityProjects) + GetProjectFrame( *project ).Raise(); } void OnMacMinimizeAll(const CommandContext &) diff --git a/src/ondemand/ODManager.cpp b/src/ondemand/ODManager.cpp index b2e2154da..f67982a03 100644 --- a/src/ondemand/ODManager.cpp +++ b/src/ondemand/ODManager.cpp @@ -424,7 +424,8 @@ void ODManager::Start() ODLocker locker{ &AudacityProject::AllProjectDeleteMutex() }; AudacityProject* proj = GetActiveProject(); if(proj) - proj->GetEventHandler()->AddPendingEvent(event); + GetProjectFrame( *proj ) + .GetEventHandler()->AddPendingEvent(event); } mTerminateMutex.Lock(); } diff --git a/src/ondemand/ODTask.cpp b/src/ondemand/ODTask.cpp index 376cd9838..afbef1f59 100644 --- a/src/ondemand/ODTask.cpp +++ b/src/ondemand/ODTask.cpp @@ -159,7 +159,8 @@ void ODTask::DoSome(float amountWork) if(IsTaskAssociatedWithProject(gAudacityProjects[i].get())) { //this assumes tasks are only associated with one project. - gAudacityProjects[i]->GetEventHandler()->AddPendingEvent(event); + GetProjectFrame( *gAudacityProjects[i] ) + .GetEventHandler()->AddPendingEvent(event); //mark the changes so that the project can be resaved. UndoManager::Get( *gAudacityProjects[i] ).SetODChangesFlag(); break; diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index 819979348..9ea88b541 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -817,7 +817,8 @@ void ControlToolBar::OnPlay(wxCommandEvent & WXUNUSED(evt)) StopPlaying(); - if (p) p->TP_DisplaySelection(); + if (p) + ProjectWindow::Get( *p ).TP_DisplaySelection(); auto cleanup = finally( [&]{ UpdateStatusBar(p); } ); PlayDefault(); @@ -1337,7 +1338,7 @@ void ControlToolBar::OnRewind(wxCommandEvent & WXUNUSED(evt)) AudacityProject *p = GetActiveProject(); if (p) { TransportActions::StopIfPaused( *p ); - p->Rewind(mRewind->WasShiftDown()); + ProjectWindow::Get( *p ).Rewind(mRewind->WasShiftDown()); } } @@ -1350,7 +1351,7 @@ void ControlToolBar::OnFF(wxCommandEvent & WXUNUSED(evt)) if (p) { TransportActions::StopIfPaused( *p ); - p->SkipEnd(mFF->WasShiftDown()); + ProjectWindow::Get( *p ).SkipEnd(mFF->WasShiftDown()); } } @@ -1442,7 +1443,8 @@ wxString ControlToolBar::StateForStatusBar() void ControlToolBar::UpdateStatusBar(AudacityProject *pProject) { - pProject->GetStatusBar()->SetStatusText(StateForStatusBar(), stateStatusBarField); + GetProjectFrame( *pProject ) + .GetStatusBar()->SetStatusText(StateForStatusBar(), stateStatusBarField); } bool ControlToolBar::IsTransportingPinned() @@ -1466,8 +1468,8 @@ void ControlToolBar::StartScrollingIfPreferred() // doing this causes wheel rotation events (mapped from the double finger vertical // swipe) to be delivered more uniformly to the application, so that speed control // works better. - ::GetActiveProject()->GetPlaybackScroller().Activate - (AudacityProject::PlaybackScroller::Mode::Refresh); + ProjectWindow::Get( *::GetActiveProject() ).GetPlaybackScroller().Activate + (ProjectWindow::PlaybackScroller::Mode::Refresh); } #endif else @@ -1476,7 +1478,7 @@ void ControlToolBar::StartScrollingIfPreferred() void ControlToolBar::StartScrolling() { - using Mode = AudacityProject::PlaybackScroller::Mode; + using Mode = ProjectWindow::PlaybackScroller::Mode; const auto project = GetActiveProject(); if (project) { auto mode = Mode::Pinned; @@ -1508,7 +1510,7 @@ void ControlToolBar::StartScrolling() } #endif - project->GetPlaybackScroller().Activate(mode); + ProjectWindow::Get( *project ).GetPlaybackScroller().Activate(mode); } } @@ -1516,8 +1518,8 @@ void ControlToolBar::StopScrolling() { const auto project = GetActiveProject(); if(project) - project->GetPlaybackScroller().Activate - (AudacityProject::PlaybackScroller::Mode::Off); + ProjectWindow::Get( *project ).GetPlaybackScroller().Activate + (ProjectWindow::PlaybackScroller::Mode::Off); } void ControlToolBar::CommitRecording() diff --git a/src/toolbars/ToolManager.cpp b/src/toolbars/ToolManager.cpp index d0d3566ef..84fc31463 100644 --- a/src/toolbars/ToolManager.cpp +++ b/src/toolbars/ToolManager.cpp @@ -83,7 +83,7 @@ // ToolFrame::ToolFrame ( AudacityProject *parent, ToolManager *manager, ToolBar *bar, wxPoint pos ) - : wxFrame( parent, + : wxFrame( ProjectWindow::Find( parent ), bar->GetId(), wxEmptyString, pos, @@ -324,7 +324,8 @@ END_EVENT_TABLE() static const AudacityProject::AttachedObjects::RegisteredFactory key{ []( AudacityProject &parent ){ - return std::make_shared< ToolManager >( &parent, parent.GetTopPanel() ); } + auto &window = ProjectWindow::Get( parent ); + return std::make_shared< ToolManager >( &parent, window.GetTopPanel() ); } }; ToolManager &ToolManager::Get( AudacityProject &project ) @@ -343,6 +344,7 @@ const ToolManager &ToolManager::Get( const AudacityProject &project ) ToolManager::ToolManager( AudacityProject *parent, wxWindow *topDockParent ) : wxEvtHandler() { + auto &window = ProjectWindow::Get( *parent ); wxPoint pt[ 3 ]; #if defined(__WXMAC__) @@ -409,19 +411,19 @@ ToolManager::ToolManager( AudacityProject *parent, wxWindow *topDockParent ) // Hook the parents mouse events...using the parent helps greatly // under GTK - mParent->Bind( wxEVT_LEFT_UP, + window.Bind( wxEVT_LEFT_UP, &ToolManager::OnMouse, this ); - mParent->Bind( wxEVT_MOTION, + window.Bind( wxEVT_MOTION, &ToolManager::OnMouse, this ); - mParent->Bind( wxEVT_MOUSE_CAPTURE_LOST, + window.Bind( wxEVT_MOUSE_CAPTURE_LOST, &ToolManager::OnCaptureLost, this ); // Create the top and bottom docks mTopDock = safenew ToolDock( this, topDockParent, TopDockID ); - mBotDock = safenew ToolDock( this, mParent, BotDockID ); + mBotDock = safenew ToolDock( this, &window, BotDockID ); // Create all of the toolbars // All have the project as parent window @@ -665,7 +667,7 @@ int ToolManager::FilterEvent(wxEvent &event) if ( window && !dynamic_cast( window ) && !dynamic_cast( window ) && - top == mParent ) + top == ProjectWindow::Find( mParent ) ) // Note this is a dangle-proof wxWindowRef: mLastFocus = window; } @@ -1050,7 +1052,7 @@ void ToolManager::Updated() { // Queue an update event wxCommandEvent e( EVT_TOOLBAR_UPDATED ); - mParent->GetEventHandler()->AddPendingEvent( e ); + GetProjectFrame( *mParent ).GetEventHandler()->AddPendingEvent( e ); } // @@ -1182,7 +1184,7 @@ void ToolManager::OnMouse( wxMouseEvent & event ) // Must set the bar afloat if it's currently docked mDidDrag = true; wxPoint mp = event.GetPosition(); - mp = mParent->ClientToScreen(mp); + mp = GetProjectFrame( *mParent ).ClientToScreen(mp); if (!mDragWindow) { // We no longer have control if (mPrevDock) @@ -1457,8 +1459,9 @@ void ToolManager::OnGrabber( GrabberEvent & event ) } // We want all mouse events from this point on - if( !mParent->HasCapture() ) - mParent->CaptureMouse(); + auto &window = GetProjectFrame( *mParent ); + if( !window.HasCapture() ) + window.CaptureMouse(); // Start monitoring shift key changes mLastState = wxGetKeyState( WXK_SHIFT ); @@ -1499,9 +1502,10 @@ void ToolManager::DoneDragging() { // Done dragging // Release capture - if( mParent->HasCapture() ) + auto &window = GetProjectFrame( *mParent ); + if( window.HasCapture() ) { - mParent->ReleaseMouse(); + window.ReleaseMouse(); } // Hide the indicator diff --git a/src/toolbars/ToolManager.h b/src/toolbars/ToolManager.h index e606c34d8..0493bef61 100644 --- a/src/toolbars/ToolManager.h +++ b/src/toolbars/ToolManager.h @@ -34,6 +34,7 @@ class wxTimerEvent; class wxWindow; class AudacityProject; +using ProjectWindow = AudacityProject; class ToolFrame; //////////////////////////////////////////////////////////// @@ -184,8 +185,6 @@ public: void Resize( const wxSize &size ); - AudacityProject *GetParent() const { return mParent; } - private: AudacityProject *const mParent; diff --git a/src/tracks/ui/CommonTrackPanelCell.cpp b/src/tracks/ui/CommonTrackPanelCell.cpp index 997ebade7..663ac89e2 100644 --- a/src/tracks/ui/CommonTrackPanelCell.cpp +++ b/src/tracks/ui/CommonTrackPanelCell.cpp @@ -48,6 +48,7 @@ unsigned CommonTrackPanelCell::HandleWheelRotation const wxMouseEvent &event = evt.event; auto &viewInfo = ViewInfo::Get( *pProject ); Scrubber &scrubber = Scrubber::Get( *pProject ); + auto &window = ProjectWindow::Get( *pProject ); const auto steps = evt.steps; if (event.ShiftDown() @@ -57,7 +58,7 @@ unsigned CommonTrackPanelCell::HandleWheelRotation ) { // MM: Scroll left/right when used with Shift key down - pProject->TP_ScrollWindow( + window.TP_ScrollWindow( viewInfo.OffsetTimeByPixels( viewInfo.PositionToTime(0), 50.0 * -steps)); } @@ -153,7 +154,7 @@ unsigned CommonTrackPanelCell::HandleWheelRotation double lines = steps * 4 + mVertScrollRemainder; mVertScrollRemainder = lines - floor(lines); lines = floor(lines); - auto didSomething = pProject->TP_ScrollUpDown((int)-lines); + auto didSomething = window.TP_ScrollUpDown((int)-lines); if (!didSomething) result |= Cancelled; } diff --git a/src/tracks/ui/PlayIndicatorOverlay.cpp b/src/tracks/ui/PlayIndicatorOverlay.cpp index 359ee299a..ff48ba8b3 100644 --- a/src/tracks/ui/PlayIndicatorOverlay.cpp +++ b/src/tracks/ui/PlayIndicatorOverlay.cpp @@ -126,7 +126,8 @@ static const AudacityProject::AttachedObjects::RegisteredFactory sOverlayKey{ PlayIndicatorOverlay::PlayIndicatorOverlay(AudacityProject *project) : PlayIndicatorOverlayBase(project, true) { - mProject->GetPlaybackScroller().Bind(EVT_TRACK_PANEL_TIMER, + ProjectWindow::Get( *mProject ).GetPlaybackScroller().Bind( + EVT_TRACK_PANEL_TIMER, &PlayIndicatorOverlay::OnTimer, this); } @@ -165,8 +166,10 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event) // Calculate the horizontal position of the indicator const double playPos = viewInfo.mRecentStreamTime; - using Mode = AudacityProject::PlaybackScroller::Mode; - const Mode mode = mProject->GetPlaybackScroller().GetMode(); + auto &window = ProjectWindow::Get( *mProject ); + using Mode = ProjectWindow::PlaybackScroller::Mode; + const Mode mode = + window.GetPlaybackScroller().GetMode(); const bool pinned = ( mode == Mode::Pinned || mode == Mode::Right ); // Use a small tolerance to avoid flicker of play head pinned all the way @@ -179,7 +182,7 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event) trackPanel.GetScreenEndTime() + tolerance); // This displays the audio time, too... - mProject->TP_DisplaySelection(); + window.TP_DisplaySelection(); // BG: Scroll screen if option is set if( viewInfo.bUpdateTrackIndicator && @@ -199,9 +202,9 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event) // just a little bit equal to the scrubbing poll interval // duration. newPos = viewInfo.OffsetTimeByPixels( newPos, -width ); - newPos = std::max( newPos, mProject->ScrollingLowerBoundTime() ); + newPos = std::max( newPos, window.ScrollingLowerBoundTime() ); } - mProject->TP_ScrollWindow(newPos); + window.TP_ScrollWindow(newPos); // Might yet be off screen, check it onScreen = playPos >= 0.0 && between_incexc(viewInfo.h, @@ -213,7 +216,7 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event) // Always update scrollbars even if not scrolling the window. This is // important when NEW audio is recorded, because this can change the // length of the project and therefore the appearance of the scrollbar. - mProject->TP_RedrawScrollbars(); + window.TP_RedrawScrollbars(); if (onScreen) mNewIndicatorX = viewInfo.TimeToPosition(playPos, trackPanel.GetLeftOffset()); diff --git a/src/tracks/ui/SelectHandle.cpp b/src/tracks/ui/SelectHandle.cpp index 77c165d33..e8983efa9 100644 --- a/src/tracks/ui/SelectHandle.cpp +++ b/src/tracks/ui/SelectHandle.cpp @@ -1067,13 +1067,14 @@ void SelectHandle::TimerHandler::OnTimer(wxCommandEvent &event) const auto project = mConnectedProject; const auto &trackPanel = TrackPanel::Get( *project ); + auto &window = ProjectWindow::Get( *project ); if (mParent->mMostRecentX >= mParent->mRect.x + mParent->mRect.width) { mParent->mAutoScrolling = true; - project->TP_ScrollRight(); + window.TP_ScrollRight(); } else if (mParent->mMostRecentX < mParent->mRect.x) { mParent->mAutoScrolling = true; - project->TP_ScrollLeft(); + window.TP_ScrollLeft(); } else { // Bug1387: enable autoscroll during drag, if the pointer is at either @@ -1084,14 +1085,14 @@ void SelectHandle::TimerHandler::OnTimer(wxCommandEvent &event) trackPanel.ClientToScreen(&xx, &yy); if (xx == 0) { mParent->mAutoScrolling = true; - project->TP_ScrollLeft(); + window.TP_ScrollLeft(); } else { int width, height; ::wxDisplaySize(&width, &height); if (xx == width - 1) { mParent->mAutoScrolling = true; - project->TP_ScrollRight(); + window.TP_ScrollRight(); } } } diff --git a/src/tracks/ui/TrackControls.cpp b/src/tracks/ui/TrackControls.cpp index d5fa6476c..d4d907160 100644 --- a/src/tracks/ui/TrackControls.cpp +++ b/src/tracks/ui/TrackControls.cpp @@ -214,7 +214,7 @@ void TrackMenuTable::OnSetName(wxCommandEvent &) SetTrackNameCommand Command; Command.mName = oldName; // Bug 1837 : We need an OK/Cancel result if we are to enter a blank string. - bool bResult = Command.PromptUser( proj ); + bool bResult = Command.PromptUser( &GetProjectFrame( *proj ) ); if (bResult) { wxString newName = Command.mName; diff --git a/src/widgets/Meter.cpp b/src/widgets/Meter.cpp index 3d4f4a217..d38e6c20c 100644 --- a/src/widgets/Meter.cpp +++ b/src/widgets/Meter.cpp @@ -1987,7 +1987,8 @@ void MeterPanel::OnPreferences(wxCommandEvent & WXUNUSED(event)) // Dialog is a child of the project, rather than of the toolbar. // This determines where it pops up. - wxDialogWrapper dlg(GetActiveProject(), wxID_ANY, title); + wxDialogWrapper dlg( FindProjectFrame( GetActiveProject() ), + wxID_ANY, title ); dlg.SetName(dlg.GetTitle()); ShuttleGui S(&dlg, eIsCreating); S.StartVerticalLay();