Audacity 3.2.0
Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
ProjectManager Class Referencefinal

Object associated with a project for high-level management of the project's lifetime, including creation, destruction, opening from file, importing, pushing undo states, and reverting to saved states. More...

#include <ProjectManager.h>

Inheritance diagram for ProjectManager:
[legend]
Collaboration diagram for ProjectManager:
[legend]

Classes

class  ProjectChooser
 Callable object that supplies the chooser argument of ProjectFileManager::OpenFile. More...
 

Public Member Functions

 ProjectManager (AudacityProject &project)
 
 ProjectManager (const ProjectManager &) PROHIBITED
 
ProjectManageroperator= (const ProjectManager &) PROHIBITED
 
 ~ProjectManager () override
 
void ResetProjectToEmpty ()
 
int GetEstimatedRecordingMinsLeftOnDisk (long lCaptureChannels=0)
 
TranslatableString GetHoursMinsString (int iMinutes)
 
void SetStatusText (const TranslatableString &text, int number)
 
void SetSkipSavePrompt (bool bSkip)
 
- Public Member Functions inherited from ClientData::Base
virtual ~Base ()
 

Static Public Member Functions

static ProjectManagerGet (AudacityProject &project)
 
static const ProjectManagerGet (const AudacityProject &project)
 
static AudacityProjectNew ()
 
static void OpenFiles (AudacityProject *proj)
 
static bool SafeToOpenProjectInto (AudacityProject &proj)
 False when it is unsafe to overwrite proj with contents of an .aup3 file. More...
 
static AudacityProjectOpenProject (AudacityProject *pGivenProject, const FilePath &fileNameArg, bool addtohistory, bool reuseNonemptyProject)
 Open a file into an AudacityProject, returning the project, or nullptr for failure. More...
 
static void SaveWindowSize ()
 
static void SetClosingAll (bool closing)
 

Private Member Functions

void OnReconnectionFailure (ProjectFileIOMessage)
 
void OnCloseWindow (wxCloseEvent &event)
 
void OnTimer (wxTimerEvent &event)
 
void OnStatusChange (StatusBarField field)
 
void RestartTimer ()
 

Private Attributes

AudacityProjectmProject
 
std::unique_ptr< wxTimer > mTimer
 
Observer::Subscription mProjectStatusSubscription
 
Observer::Subscription mProjectFileIOSubscription
 

Static Private Attributes

static bool sbWindowRectAlreadySaved = false
 
static bool sbSkipPromptingForSave = false
 

Detailed Description

Object associated with a project for high-level management of the project's lifetime, including creation, destruction, opening from file, importing, pushing undo states, and reverting to saved states.

Definition at line 33 of file ProjectManager.h.

Constructor & Destructor Documentation

◆ ProjectManager() [1/2]

ProjectManager::ProjectManager ( AudacityProject project)
explicit

Definition at line 95 of file ProjectManager.cpp.

96 : mProject{ project }
97 , mTimer{ std::make_unique<wxTimer>(this, AudacityProjectTimerID) }
98{
99 auto &window = ProjectWindow::Get( mProject );
100 window.Bind( wxEVT_CLOSE_WINDOW, &ProjectManager::OnCloseWindow, this );
105}
const int AudacityProjectTimerID
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
static ProjectFileIO & Get(AudacityProject &project)
void OnStatusChange(StatusBarField field)
void OnCloseWindow(wxCloseEvent &event)
std::unique_ptr< wxTimer > mTimer
Observer::Subscription mProjectFileIOSubscription
AudacityProject & mProject
Observer::Subscription mProjectStatusSubscription
void OnReconnectionFailure(ProjectFileIOMessage)
static ProjectStatus & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)

References ProjectStatus::Get(), ProjectFileIO::Get(), ProjectWindow::Get(), mProject, mProjectFileIOSubscription, mProjectStatusSubscription, OnCloseWindow(), OnReconnectionFailure(), OnStatusChange(), and Observer::Publisher< Message, NotifyAll >::Subscribe().

Here is the call graph for this function:

◆ ProjectManager() [2/2]

ProjectManager::ProjectManager ( const ProjectManager )

◆ ~ProjectManager()

ProjectManager::~ProjectManager ( )
overridedefault

Member Function Documentation

◆ Get() [1/2]

ProjectManager & ProjectManager::Get ( AudacityProject project)
static

Definition at line 85 of file ProjectManager.cpp.

86{
87 return project.AttachedObjects::Get< ProjectManager >( sProjectManagerKey );
88}
static AudacityProject::AttachedObjects::RegisteredFactory sProjectManagerKey
Object associated with a project for high-level management of the project's lifetime,...

References sProjectManagerKey.

Referenced by Get(), InitProjectWindow(), New(), ApplyMacroDialog::OnApplyToFiles(), TimerRecordDialog::OnOK(), anonymous_namespace{FileMenus.cpp}::OnProjectReset(), and anonymous_namespace{TimerRecordDialog.cpp}::OnTimerRecord().

Here is the caller graph for this function:

◆ Get() [2/2]

const ProjectManager & ProjectManager::Get ( const AudacityProject project)
static

Definition at line 90 of file ProjectManager.cpp.

91{
92 return Get( const_cast< AudacityProject & >( project ) );
93}
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static ProjectManager & Get(AudacityProject &project)

References Get().

Here is the call graph for this function:

◆ GetEstimatedRecordingMinsLeftOnDisk()

int ProjectManager::GetEstimatedRecordingMinsLeftOnDisk ( long  lCaptureChannels = 0)

Definition at line 865 of file ProjectManager.cpp.

865 {
866 auto &project = mProject;
867
868 // Obtain the current settings
869 auto oCaptureFormat = QualitySettings::SampleFormatChoice();
870 if (lCaptureChannels == 0)
871 lCaptureChannels = AudioIORecordChannels.Read();
872
873 // Find out how much free space we have on disk
874 wxLongLong lFreeSpace = ProjectFileIO::Get( project ).GetFreeDiskSpace();
875 if (lFreeSpace < 0) {
876 return 0;
877 }
878
879 // Calculate the remaining time
880 double dRecTime = 0.0;
881 double bytesOnDiskPerSample = SAMPLE_SIZE_DISK(oCaptureFormat);
882 dRecTime = lFreeSpace.GetHi() * 4294967296.0 + lFreeSpace.GetLo();
883 dRecTime /= bytesOnDiskPerSample;
884 dRecTime /= lCaptureChannels;
885 dRecTime /= ProjectRate::Get( project ).GetRate();
886
887 // Convert to minutes before returning
888 int iRecMins = (int)round(dRecTime / 60.0);
889 return iRecMins;
890}
IntSetting AudioIORecordChannels
#define SAMPLE_SIZE_DISK(SampleFormat)
Return the size on disk of one uncompressed sample (bytes)
Definition: SampleFormat.h:65
wxLongLong GetFreeDiskSpace() const
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
double GetRate() const
Definition: ProjectRate.cpp:53
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:200
PROJECT_RATE_API sampleFormat SampleFormatChoice()
fastfloat_really_inline void round(adjusted_mantissa &am, callback cb) noexcept
Definition: fast_float.h:2512

References AudioIORecordChannels, ProjectRate::Get(), ProjectFileIO::Get(), ProjectFileIO::GetFreeDiskSpace(), ProjectRate::GetRate(), mProject, Setting< T >::Read(), fast_float::round(), SAMPLE_SIZE_DISK, and QualitySettings::SampleFormatChoice().

Referenced by OnTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetHoursMinsString()

TranslatableString ProjectManager::GetHoursMinsString ( int  iMinutes)

Definition at line 843 of file ProjectManager.cpp.

844{
845 if (iMinutes < 1)
846 // Less than a minute...
847 return XO("Less than 1 minute");
848
849 // Calculate
850 int iHours = iMinutes / 60;
851 int iMins = iMinutes % 60;
852
853 auto sHours = XP( "%d hour", "%d hours", 0 )( iHours );
854
855 auto sMins = XP( "%d minute", "%d minutes", 0 )( iMins );
856
857 /* i18n-hint: A time in hours and minutes. Only translate the "and". */
858 return XO("%s and %s.").Format( sHours, sMins );
859}
XO("Cut/Copy/Paste")
#define XP(sing, plur, n)
Definition: Internat.h:96

References XO(), and XP.

Referenced by OnTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ New()

AudacityProject * ProjectManager::New ( )
static

Definition at line 327 of file ProjectManager.cpp.

328{
329 wxRect wndRect;
330 bool bMaximized = false;
331 bool bIconized = false;
332 GetNextWindowPlacement(&wndRect, &bMaximized, &bIconized);
333
334 // Create and show a NEW project
335 // Use a non-default deleter in the smart pointer!
336 auto sp = AudacityProject::Create();
337 AllProjects{}.Add( sp );
338 auto p = sp.get();
339 auto &project = *p;
340 auto &projectHistory = ProjectHistory::Get( project );
341 auto &projectManager = Get( project );
342 auto &window = ProjectWindow::Get( *p );
343
344 // Issue #2569
345 // There is a dependency on the order of initialisation.
346 // The menus must be created, and registered, before
347 // InitProjectWindows can UpdateMenus.
349
350 InitProjectWindow( window );
351
352 // wxGTK3 seems to need to require creating the window using default position
353 // and then manually positioning it.
354 window.SetPosition(wndRect.GetPosition());
355
356 auto &projectFileManager = ProjectFileManager::Get( *p );
357
358 // This may report an error.
359 projectFileManager.OpenNewProject();
360
361 projectHistory.InitialState();
362 projectManager.RestartTimer();
363
364 if(bMaximized) {
365 window.Maximize(true);
366 }
367 else if (bIconized) {
368 // if the user close down and iconized state we could start back up and iconized state
369 // window.Iconize(TRUE);
370 }
371
372 //Initialise the Listeners
373 auto gAudioIO = AudioIO::Get();
374 gAudioIO->SetListener(
375 ProjectAudioManager::Get( project ).shared_from_this() );
376 auto &projectSelectionManager = ProjectSelectionManager::Get( project );
377 SelectionBar::Get( project ).SetListener( &projectSelectionManager );
378#ifdef EXPERIMENTAL_SPECTRAL_EDITING
379 SpectralSelectionBar::Get( project ).SetListener( &projectSelectionManager );
380#endif
381 TimeToolBar::Get( project ).SetListener( &projectSelectionManager );
382
383 //Set the NEW project as active:
385
386 // Okay, GetActiveProject() is ready. Now we can get its CommandManager,
387 // and add the shortcut keys to the tooltips.
389
391
392 window.Show(true);
393
394 return p;
395}
void SetActiveProject(AudacityProject *project)
@ ProjectInitialized
void InitProjectWindow(ProjectWindow &window)
void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized)
void Add(const value_type &pProject)
This invalidates iterators.
Definition: Project.cpp:56
static std::shared_ptr< AudacityProject > Create()
Use this factory function.
Definition: Project.cpp:78
static AudioIO * Get()
Definition: AudioIO.cpp:147
void CreateMenusAndCommands(AudacityProject &project)
Definition: Menus.cpp:376
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:69
static ModuleManager & Get()
int Dispatch(ModuleDispatchTypes type)
static ProjectAudioManager & Get(AudacityProject &project)
static ProjectFileManager & Get(AudacityProject &project)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSelectionManager & Get(AudacityProject &project)
void SetListener(SelectionBarListener *l)
static SelectionBar & Get(AudacityProject &project)
static SpectralSelectionBar & Get(AudacityProject &project)
void SetListener(SpectralSelectionBarListener *l)
static TimeToolBar & Get(AudacityProject &project)
Definition: TimeToolBar.cpp:74
void SetListener(TimeToolBarListener *l)
static ToolManager & Get(AudacityProject &project)
void RegenerateTooltips()

References AllProjects::Add(), AudacityProject::Create(), MenuCreator::CreateMenusAndCommands(), ModuleManager::Dispatch(), AudioIO::Get(), ModuleManager::Get(), ProjectHistory::Get(), MenuManager::Get(), ProjectAudioManager::Get(), ProjectFileManager::Get(), Get(), ProjectSelectionManager::Get(), ProjectWindow::Get(), SelectionBar::Get(), SpectralSelectionBar::Get(), TimeToolBar::Get(), ToolManager::Get(), GetNextWindowPlacement(), InitProjectWindow(), ProjectInitialized, ToolManager::RegenerateTooltips(), SetActiveProject(), SelectionBar::SetListener(), SpectralSelectionBar::SetListener(), and TimeToolBar::SetListener().

Referenced by DoImportMIDIProject(), AudacityApp::InitPart2(), AudacityApp::MacNewFile(), OnCloseWindow(), AudacityApp::OnMenuNew(), anonymous_namespace{FileMenus.cpp}::OnNew(), and ProjectManager::ProjectChooser::operator()().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnCloseWindow()

void ProjectManager::OnCloseWindow ( wxCloseEvent &  event)
private

Definition at line 410 of file ProjectManager.cpp.

411{
412 auto &project = mProject;
413 auto &projectFileIO = ProjectFileIO::Get( project );
414 auto &projectFileManager = ProjectFileManager::Get( project );
415 const auto &settings = ProjectSettings::Get( project );
416 auto &projectAudioIO = ProjectAudioIO::Get( project );
417 auto &tracks = TrackList::Get( project );
418 auto &window = ProjectWindow::Get( project );
419 auto gAudioIO = AudioIO::Get();
420
421 // We are called for the wxEVT_CLOSE_WINDOW, wxEVT_END_SESSION, and
422 // wxEVT_QUERY_END_SESSION, so we have to protect against multiple
423 // entries. This is a hack until the whole application termination
424 // process can be reviewed and reworked. (See bug #964 for ways
425 // to exercise the bug that instigated this hack.)
426 if (window.IsBeingDeleted())
427 {
428 event.Skip();
429 return;
430 }
431
432 if (event.CanVeto() && (::wxIsBusy() || project.mbBusyImporting))
433 {
434 event.Veto();
435 return;
436 }
437
438 // Check to see if we were playing or recording
439 // audio, and if so, make sure Audio I/O is completely finished.
440 // The main point of this is to properly push the state
441 // and flush the tracks once we've completely finished
442 // recording NEW state.
443 // This code is derived from similar code in
444 // AudacityProject::~AudacityProject() and TrackPanel::OnTimer().
445 if (projectAudioIO.GetAudioIOToken()>0 &&
446 gAudioIO->IsStreamActive(projectAudioIO.GetAudioIOToken())) {
447
448 // We were playing or recording audio, but we've stopped the stream.
449 ProjectAudioManager::Get( project ).Stop();
450
451 projectAudioIO.SetAudioIOToken(0);
452 window.RedrawProject();
453 }
454 else if (gAudioIO->IsMonitoring()) {
455 gAudioIO->StopStream();
456 }
457
458 // MY: Use routine here so other processes can make same check
459 bool bHasTracks = !tracks.empty();
460
461 // We may not bother to prompt the user to save, if the
462 // project is now empty.
464 && event.CanVeto()
465 && (settings.EmptyCanBeDirty() || bHasTracks)) {
466 if ( UndoManager::Get( project ).UnsavedChanges() ) {
467 TitleRestorer Restorer( window, project );// RAII
468 /* i18n-hint: The first %s numbers the project, the second %s is the project name.*/
469 auto Title = XO("%sSave changes to %s?")
470 .Format( Restorer.sProjNumber, Restorer.sProjName );
471 auto Message = XO("Save project before closing?");
472 if( !bHasTracks )
473 {
474 Message += XO("\nIf saved, the project will have no tracks.\n\nTo save any previously open tracks:\nCancel, Edit > Undo until all tracks\nare open, then File > Save Project.");
475 }
476 int result = AudacityMessageBox(
477 Message,
478 Title,
479 wxYES_NO | wxCANCEL | wxICON_QUESTION,
480 &window);
481
482 if (result == wxCANCEL || (result == wxYES &&
483 !GuardedCall<bool>( [&]{ return projectFileManager.Save(); } )
484 )) {
485 event.Veto();
486 return;
487 }
488 }
489 }
490#ifdef __WXMAC__
491 // Fix bug apparently introduced into 2.1.2 because of wxWidgets 3:
492 // closing a project that was made full-screen (as by clicking the green dot
493 // or command+/; not merely "maximized" as by clicking the title bar or
494 // Zoom in the Window menu) leaves the screen black.
495 // Fix it by un-full-screening.
496 // (But is there a different way to do this? What do other applications do?
497 // I don't see full screen windows of Safari shrinking, but I do see
498 // momentary blackness.)
499 window.ShowFullScreen(false);
500#endif
501
502 // This achieves auto save on close of project before other important
503 // project state is destroyed
504 window.Publish(ProjectWindowDestroyedMessage {});
506
507 // Stop the timer since there's no need to update anything anymore
508 mTimer.reset();
509
510 // DMM: Save the size of the last window the user closes
511 //
512 // LL: Save before doing anything else to the window that might make
513 // its size change.
515
516 window.SetIsBeingDeleted();
517
518 // Mac: we never quit as the result of a close.
519 // Other systems: we quit only when the close is the result of an external
520 // command (on Windows, those are taskbar closes, "X" box, Alt+F4, etc.)
521 bool quitOnClose;
522#ifdef __WXMAC__
523 quitOnClose = false;
524#else
525 quitOnClose = !projectFileManager.GetMenuClose();
526#endif
527
528 // DanH: If we're definitely about to quit, clear the clipboard.
529 auto &clipboard = Clipboard::Get();
530 if ((AllProjects{}.size() == 1) &&
531 (quitOnClose || sbClosingAll))
532 clipboard.Clear();
533 else {
534 auto clipboardProject = clipboard.Project().lock();
535 if ( clipboardProject.get() == &mProject ) {
536 // Closing the project from which content was cut or copied.
537 // For 3.0.0, clear the clipboard, because accessing clipboard contents
538 // would depend on a database connection to the closing project, but
539 // that connection should closed now so that the project file can be
540 // freely moved.
541 // Notes:
542 // 1) maybe clipboard contents could be saved by migrating them to
543 // another temporary database, but that extra effort is beyond the
544 // scope of 3.0.0.
545 // 2) strictly speaking this is necessary only when the clipboard
546 // contains WaveTracks.
547 clipboard.Clear();
548 }
549 }
550
551 // JKC: For Win98 and Linux do not detach the menu bar.
552 // We want wxWidgets to clean it up for us.
553 // TODO: Is there a Mac issue here??
554 // SetMenuBar(NULL);
555
556 // Compact the project.
557 projectFileManager.CompactProjectOnClose();
558
559 // Set (or not) the bypass flag to indicate that deletes that would happen during
560 // the UndoManager::ClearStates() below are not necessary.
561 projectFileIO.SetBypass();
562
563 {
564 // This can reduce reference counts of sample blocks in the project's
565 // tracks.
566 UndoManager::Get( project ).ClearStates();
567
568 // Delete all the tracks to free up memory
569 tracks.Clear();
570 }
571
572 // Some of the AdornedRulerPanel functions refer to the TrackPanel, so destroy this
573 // before the TrackPanel is destroyed. This change was needed to stop Audacity
574 // crashing when running with Jaws on Windows 10 1703.
576
577 // Destroy the TrackPanel early so it's not around once we start
578 // deleting things like tracks and such out from underneath it.
579 // Check validity of mTrackPanel per bug 584 Comment 1.
580 // Deeper fix is in the Import code, but this failsafes against crash.
581 TrackPanel::Destroy( project );
582 // Finalize the tool manager before the children since it needs
583 // to save the state of the toolbars.
584 ToolManager::Get( project ).Destroy();
585
586 window.DestroyChildren();
587
588 // Close project only now, because TrackPanel might have been holding
589 // some shared_ptr to WaveTracks keeping SampleBlocks alive.
590 // We're all done with the project file, so close it now
591 projectFileManager.CloseProject();
592
593 WaveTrackFactory::Destroy( project );
594
595 // Remove self from the global array, but defer destruction of self
596 auto pSelf = AllProjects{}.Remove( project );
597 wxASSERT( pSelf );
598
599 if (GetActiveProject().lock().get() == &project) {
600 // Find a NEW active project
601 if ( !AllProjects{}.empty() ) {
603 }
604 else {
605 SetActiveProject(nullptr);
606 }
607 }
608
609 // Since we're going to be destroyed, make sure we're not to
610 // receive audio notifications anymore.
611 // PRL: Maybe all this is unnecessary now that the listener is managed
612 // by a weak pointer.
613 if ( gAudioIO->GetListener().get() == &ProjectAudioManager::Get( project ) ) {
614 auto active = GetActiveProject().lock();
615 gAudioIO->SetListener(
616 active
617 ? ProjectAudioManager::Get( *active ).shared_from_this()
618 : nullptr
619 );
620 }
621
622 if (AllProjects{}.empty() && !sbClosingAll) {
623
624#if !defined(__WXMAC__)
625 if (quitOnClose) {
626 // Simulate the application Exit menu item
627 wxCommandEvent evt{ wxEVT_MENU, wxID_EXIT };
628 wxTheApp->AddPendingEvent( evt );
629 }
630 else {
632 // For non-Mac, always keep at least one project window open
633 (void) New();
634 }
635#endif
636 }
637
638 window.Destroy();
639
640 // Destroys this
641 pSelf.reset();
642}
AUDACITY_DLL_API std::weak_ptr< AudacityProject > GetActiveProject()
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
@ ProjectClosing
static bool sbClosingAll
static Settings & settings()
Definition: TrackInfo.cpp:87
static void Destroy(AudacityProject &project)
size_t size() const
Definition: Project.cpp:17
value_type Remove(AudacityProject &project)
Definition: Project.cpp:42
const_iterator begin() const
Definition: Project.cpp:22
bool empty() const
Definition: Project.h:47
static Clipboard & Get()
Definition: Clipboard.cpp:28
static ProjectAudioIO & Get(AudacityProject &project)
void Stop(bool stopStream=true)
static bool sbWindowRectAlreadySaved
static bool sbSkipPromptingForSave
static AudacityProject * New()
static void SaveWindowSize()
static ProjectSettings & Get(AudacityProject &project)
void Destroy()
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:486
static void Destroy(AudacityProject &project)
Definition: TrackPanel.cpp:240
void ClearStates()
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:67
static void Destroy(AudacityProject &project)
Definition: WaveTrack.cpp:2814
TranslatableString Message(unsigned trackCount)
Message sent when the project window is closed.
Definition: ProjectWindow.h:32

References AudacityMessageBox(), AllProjects::begin(), UndoManager::ClearStates(), ToolManager::Destroy(), AdornedRulerPanel::Destroy(), TrackPanel::Destroy(), WaveTrackFactory::Destroy(), ModuleManager::Dispatch(), AllProjects::empty(), AudioIO::Get(), ModuleManager::Get(), Clipboard::Get(), ProjectAudioIO::Get(), UndoManager::Get(), TrackList::Get(), ProjectAudioManager::Get(), ProjectFileIO::Get(), ProjectFileManager::Get(), ProjectSettings::Get(), ProjectWindow::Get(), ToolManager::Get(), GetActiveProject(), anonymous_namespace{TrackSelectHandle.cpp}::Message(), mProject, mTimer, New(), ProjectClosing, AllProjects::Remove(), SaveWindowSize(), sbClosingAll, sbSkipPromptingForSave, sbWindowRectAlreadySaved, SetActiveProject(), settings(), AllProjects::size(), TitleRestorer::sProjName, TitleRestorer::sProjNumber, ProjectAudioManager::Stop(), and XO().

Referenced by ProjectManager().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnReconnectionFailure()

void ProjectManager::OnReconnectionFailure ( ProjectFileIOMessage  message)
private

Definition at line 397 of file ProjectManager.cpp.

398{
400 ProjectWindow::Get(mProject).Close(true);
401}

References ProjectWindow::Get(), mProject, and ReconnectionFailure.

Referenced by ProjectManager().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnStatusChange()

void ProjectManager::OnStatusChange ( StatusBarField  field)
private

Definition at line 809 of file ProjectManager.cpp.

810{
811 auto &project = mProject;
812
813 // Be careful to null-check the window. We might get to this function
814 // during shut-down, but a timer hasn't been told to stop sending its
815 // messages yet.
816 auto pWindow = ProjectWindow::Find( &project );
817 if ( !pWindow )
818 return;
819 auto &window = *pWindow;
820
821 window.UpdateStatusWidths();
822
823 const auto &msg = ProjectStatus::Get( project ).Get( field );
824 SetStatusText( msg, field );
825
826 if ( field == mainStatusBarField )
827 // When recording, let the NEW status message stay at least as long as
828 // the timer interval (if it is not replaced again by this function),
829 // before replacing it with the message about remaining disk capacity.
830 RestartTimer();
831}
#define field(n, t)
Definition: ImportAUP.cpp:166
@ mainStatusBarField
Definition: ProjectStatus.h:26
void SetStatusText(const TranslatableString &text, int number)
static ProjectWindow * Find(AudacityProject *pProject)

References field, ProjectWindow::Find(), ProjectStatus::Get(), mainStatusBarField, mProject, RestartTimer(), and SetStatusText().

Referenced by ProjectManager().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnTimer()

void ProjectManager::OnTimer ( wxTimerEvent &  event)
private

Definition at line 779 of file ProjectManager.cpp.

780{
781 auto &project = mProject;
782 auto &projectAudioIO = ProjectAudioIO::Get( project );
783 auto meterToolBars = MeterToolBar::GetToolBars( project );
784
785 for (auto& meterToolBar : meterToolBars)
786 meterToolBar.get().UpdateControls();
787
788 auto gAudioIO = AudioIO::Get();
789 // gAudioIO->GetNumCaptureChannels() should only be positive
790 // when we are recording.
791 if (projectAudioIO.GetAudioIOToken() > 0 && gAudioIO->GetNumCaptureChannels() > 0) {
792 wxLongLong freeSpace = ProjectFileIO::Get(project).GetFreeDiskSpace();
793 if (freeSpace >= 0) {
794
795 int iRecordingMins = GetEstimatedRecordingMinsLeftOnDisk(gAudioIO->GetNumCaptureChannels());
796 auto sMessage = XO("Disk space remaining for recording: %s")
797 .Format( GetHoursMinsString(iRecordingMins) );
798
799 // Do not change mLastMainStatusMessage
801 }
802 }
803
804 // As also with the TrackPanel timer: wxTimer may be unreliable without
805 // some restarts
806 RestartTimer();
807}
static MeterToolBars GetToolBars(AudacityProject &project)
TranslatableString GetHoursMinsString(int iMinutes)
int GetEstimatedRecordingMinsLeftOnDisk(long lCaptureChannels=0)

References AudioIO::Get(), ProjectAudioIO::Get(), ProjectFileIO::Get(), GetEstimatedRecordingMinsLeftOnDisk(), ProjectFileIO::GetFreeDiskSpace(), GetHoursMinsString(), MeterToolBar::GetToolBars(), mainStatusBarField, mProject, RestartTimer(), SetStatusText(), and XO().

Here is the call graph for this function:

◆ OpenFiles()

void ProjectManager::OpenFiles ( AudacityProject proj)
static

Definition at line 645 of file ProjectManager.cpp.

646{
647 auto selectedFiles =
648 ProjectFileManager::ShowOpenDialog(FileNames::Operation::Open);
649 if (selectedFiles.size() == 0) {
651 return;
652 }
653
654 //first sort selectedFiles.
655 selectedFiles.Sort(FileNames::CompareNoCase);
656
657 auto cleanup = finally( [] {
659 } );
660
661 for (const auto &fileName : selectedFiles) {
662 // Make sure it isn't already open.
664 continue; // Skip ones that are already open.
665
666 proj = OpenProject( proj, fileName,
667 true /* addtohistory */, false /* reuseNonemptyProject */ );
668 }
669}
static void SetLastOpenType(const FileNames::FileType &type)
Definition: Import.cpp:222
static bool IsAlreadyOpen(const FilePath &projPathName)
static wxArrayString ShowOpenDialog(FileNames::Operation op, const FileNames::FileType &extraType={})
Show an open dialogue for opening audio files, and possibly other sorts of files.
static AudacityProject * OpenProject(AudacityProject *pGivenProject, const FilePath &fileNameArg, bool addtohistory, bool reuseNonemptyProject)
Open a file into an AudacityProject, returning the project, or nullptr for failure.
FILES_API int CompareNoCase(const wxString &first, const wxString &second)

References FileNames::CompareNoCase(), ProjectFileManager::IsAlreadyOpen(), OpenProject(), Importer::SetLastOpenType(), and ProjectFileManager::ShowOpenDialog().

Referenced by OpenProjectCommand::Apply(), AudacityApp::OnMenuOpen(), and anonymous_namespace{FileMenus.cpp}::OnOpen().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OpenProject()

AudacityProject * ProjectManager::OpenProject ( AudacityProject pGivenProject,
const FilePath fileNameArg,
bool  addtohistory,
bool  reuseNonemptyProject 
)
static

Open a file into an AudacityProject, returning the project, or nullptr for failure.

If an exception escapes this function, no projects are created.

Parameters
pGivenProjectif not null, a project that may be reused
fileNameArgpath to the file to open; not always an Audacity project file, may be an import
addtohistorywhether to add .aup3 files to the MRU list (but always done for imports)
reuseNonemptyProjectif true, may reuse the given project when nonempty, but only if importing (not for a project file)

Definition at line 728 of file ProjectManager.cpp.

731{
732 ProjectManager::ProjectChooser chooser{ pGivenProject, reuseNonemptyProject };
733 if (auto pProject = ProjectFileManager::OpenFile(
734 std::ref(chooser), fileNameArg, addtohistory )) {
735 chooser.Commit();
736
737 auto &projectFileIO = ProjectFileIO::Get( *pProject );
738 if( projectFileIO.IsRecovered() ) {
739 auto &window = ProjectWindow::Get( *pProject );
740 window.Zoom( window.GetZoomOfToFit() );
741 // "Project was recovered" replaces "Create new project" in Undo History.
742 auto &undoManager = UndoManager::Get( *pProject );
743 undoManager.RemoveStates(0, 1);
744 }
745 return pProject;
746 }
747 return nullptr;
748}
static AudacityProject * OpenFile(const ProjectChooserFn &chooser, const FilePath &fileName, bool addtohistory=true)
Callable object that supplies the chooser argument of ProjectFileManager::OpenFile.

References UndoManager::Get(), ProjectFileIO::Get(), ProjectWindow::Get(), and ProjectFileManager::OpenFile().

Referenced by EVT_MENU_RANGE(), LOFImportFileHandle::lofOpenFiles(), OpenFiles(), and RecoverAllProjects().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=()

ProjectManager & ProjectManager::operator= ( const ProjectManager )

◆ ResetProjectToEmpty()

void ProjectManager::ResetProjectToEmpty ( )

Definition at line 751 of file ProjectManager.cpp.

751 {
752 auto &project = mProject;
753 auto &projectFileIO = ProjectFileIO::Get( project );
754 auto &projectFileManager = ProjectFileManager::Get( project );
755 auto &projectHistory = ProjectHistory::Get( project );
756 auto &viewInfo = ViewInfo::Get( project );
757
760
761 WaveTrackFactory::Reset( project );
762
763 // InitialState will reset UndoManager
764 projectHistory.InitialState();
765 projectHistory.SetDirty(false);
766
767 projectFileManager.CloseProject();
768 projectFileManager.OpenProject();
769}
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:234
static WaveTrackFactory & Reset(AudacityProject &project)
Definition: WaveTrack.cpp:2807
void DoSelectAll(AudacityProject &project)
void DoRemoveTracks(AudacityProject &project)

References TrackUtilities::DoRemoveTracks(), SelectUtilities::DoSelectAll(), ProjectHistory::Get(), ViewInfo::Get(), ProjectFileIO::Get(), ProjectFileManager::Get(), mProject, and WaveTrackFactory::Reset().

Referenced by ApplyMacroDialog::OnApplyToFiles(), and anonymous_namespace{FileMenus.cpp}::OnProjectReset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RestartTimer()

void ProjectManager::RestartTimer ( )
private

Definition at line 771 of file ProjectManager.cpp.

772{
773 if (mTimer) {
774 // mTimer->Stop(); // not really needed
775 mTimer->Start( 3000 ); // Update messages as needed once every 3 s.
776 }
777}

References mTimer.

Referenced by OnStatusChange(), and OnTimer().

Here is the caller graph for this function:

◆ SafeToOpenProjectInto()

bool ProjectManager::SafeToOpenProjectInto ( AudacityProject proj)
static

False when it is unsafe to overwrite proj with contents of an .aup3 file.

Definition at line 671 of file ProjectManager.cpp.

672{
673 // DMM: If the project is dirty, that means it's been touched at
674 // all, and it's not safe to open a fresh project directly in its
675 // place. Only if the project is brandnew clean and the user
676 // hasn't done any action at all is it safe for Open to take place
677 // inside the current project.
678 //
679 // If you try to Open a fresh project inside the current window when
680 // there are no tracks, but there's an Undo history, etc, then
681 // bad things can happen, including orphan blocks, or tracks
682 // referring to non-existent blocks
683 if (
684 ProjectHistory::Get( proj ).GetDirty() ||
685 !TrackList::Get( proj ).empty()
686 )
687 return false;
688 // This project is clean; it's never been touched. Therefore
689 // all relevant member variables are in their initial state,
690 // and it's okay to open a NEW project inside its window.
691 return true;
692}

References ProjectHistory::Get(), and TrackList::Get().

Referenced by ProjectManager::ProjectChooser::operator()().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveWindowSize()

void ProjectManager::SaveWindowSize ( )
static

Definition at line 116 of file ProjectManager.cpp.

117{
119 {
120 return;
121 }
122 bool validWindowForSaveWindowSize = FALSE;
123 ProjectWindow * validProject = nullptr;
124 bool foundIconizedProject = FALSE;
125 for ( auto pProject : AllProjects{} )
126 {
127 auto &window = ProjectWindow::Get( *pProject );
128 if (!window.IsIconized()) {
129 validWindowForSaveWindowSize = TRUE;
130 validProject = &window;
131 break;
132 }
133 else
134 foundIconizedProject = TRUE;
135 }
136
137 if (validWindowForSaveWindowSize)
138 {
139 wxRect windowRect = validProject->GetRect();
140 wxRect normalRect = validProject->GetNormalizedWindowState();
141 bool wndMaximized = validProject->IsMaximized();
142
143 SaveWindowPreferences(windowRect, normalRect, wndMaximized, false);
144 }
145 else
146 {
147 if (foundIconizedProject) {
148 validProject = &ProjectWindow::Get( **AllProjects{}.begin() );
149 bool wndMaximized = validProject->IsMaximized();
150 wxRect normalRect = validProject->GetNormalizedWindowState();
151
152 // store only the normal rectangle because the itemized rectangle
153 // makes no sense for an opening project window
154 SaveWindowPreferences(normalRect, normalRect, wndMaximized, true);
155 }
156 else {
157 // this would be a very strange case that might possibly occur on the Mac
158 // Audacity would have to be running with no projects open
159 // in this case we are going to write only the default values
160 wxRect defWndRect;
161 GetDefaultWindowRect(&defWndRect);
162 SaveWindowPreferences(defWndRect, defWndRect, false, false);
163 }
164 }
166}
void GetDefaultWindowRect(wxRect *defRect)
A top-level window associated with a project, and handling scrollbars and zooming.
Definition: ProjectWindow.h:40
wxRect GetNormalizedWindowState() const
void SaveWindowPreferences(const wxRect &windowRect, const wxRect &normalRect, bool isMaximized, bool isIconized)

References AllProjects::begin(), ProjectWindow::Get(), GetDefaultWindowRect(), ProjectWindow::GetNormalizedWindowState(), and anonymous_namespace{ProjectManager.cpp}::SaveWindowPreferences().

Referenced by OnCloseWindow(), AudacityApp::OnEndSession(), and QuitAudacity().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetClosingAll()

void ProjectManager::SetClosingAll ( bool  closing)
static

Definition at line 405 of file ProjectManager.cpp.

406{
407 sbClosingAll = closing;
408}

References sbClosingAll.

Referenced by CloseAllProjects().

Here is the caller graph for this function:

◆ SetSkipSavePrompt()

void ProjectManager::SetSkipSavePrompt ( bool  bSkip)
inline

Definition at line 114 of file ProjectManager.h.

114{ sbSkipPromptingForSave = bSkip; };

Referenced by anonymous_namespace{TimerRecordDialog.cpp}::OnTimerRecord().

Here is the caller graph for this function:

◆ SetStatusText()

void ProjectManager::SetStatusText ( const TranslatableString text,
int  number 
)

Definition at line 833 of file ProjectManager.cpp.

834{
835 auto &project = mProject;
836 auto pWindow = ProjectWindow::Find( &project );
837 if ( !pWindow )
838 return;
839 auto &window = *pWindow;
840 window.GetStatusBar()->SetStatusText(text.Translation(), number);
841}
wxString Translation() const

References ProjectWindow::Find(), mProject, and TranslatableString::Translation().

Referenced by InitProjectWindow(), OnStatusChange(), and OnTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mProject

AudacityProject& ProjectManager::mProject
private

◆ mProjectFileIOSubscription

Observer::Subscription ProjectManager::mProjectFileIOSubscription
private

Definition at line 132 of file ProjectManager.h.

Referenced by ProjectManager().

◆ mProjectStatusSubscription

Observer::Subscription ProjectManager::mProjectStatusSubscription
private

Definition at line 131 of file ProjectManager.h.

Referenced by ProjectManager().

◆ mTimer

std::unique_ptr<wxTimer> ProjectManager::mTimer
private

Definition at line 129 of file ProjectManager.h.

Referenced by OnCloseWindow(), and RestartTimer().

◆ sbSkipPromptingForSave

bool ProjectManager::sbSkipPromptingForSave = false
staticprivate

Definition at line 137 of file ProjectManager.h.

Referenced by OnCloseWindow().

◆ sbWindowRectAlreadySaved

bool ProjectManager::sbWindowRectAlreadySaved = false
staticprivate

Definition at line 136 of file ProjectManager.h.

Referenced by OnCloseWindow().


The documentation for this class was generated from the following files: