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 &)=delete
 
ProjectManageroperator= (const ProjectManager &)=delete
 
 ~ProjectManager () override
 
void ResetProjectToEmpty ()
 
int GetEstimatedRecordingMinsLeftOnDisk (long lCaptureChannels=0)
 
TranslatableString GetHoursMinsString (int iMinutes)
 
void SetStatusText (const TranslatableString &text, const StatusBarField &field)
 
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 89 of file ProjectManager.cpp.

90 : mProject{ project }
91 , mTimer{ std::make_unique<wxTimer>(this, AudacityProjectTimerID) }
92{
93 auto &window = ProjectWindow::Get( mProject );
94 window.Bind( wxEVT_CLOSE_WINDOW, &ProjectManager::OnCloseWindow, this );
99}
const int AudacityProjectTimerID
const auto project
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 ProjectFileIO::Get(), ProjectStatus::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 )
delete

◆ ~ProjectManager()

ProjectManager::~ProjectManager ( )
overridedefault

Member Function Documentation

◆ Get() [1/2]

ProjectManager & ProjectManager::Get ( AudacityProject project)
static

Definition at line 79 of file ProjectManager.cpp.

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

References project, and 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 84 of file ProjectManager.cpp.

85{
86 return Get( const_cast< AudacityProject & >( project ) );
87}
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(), and project.

Here is the call graph for this function:

◆ GetEstimatedRecordingMinsLeftOnDisk()

int ProjectManager::GetEstimatedRecordingMinsLeftOnDisk ( long  lCaptureChannels = 0)

Definition at line 855 of file ProjectManager.cpp.

855 {
856 auto &project = mProject;
857
858 // Obtain the current settings
859 auto oCaptureFormat = QualitySettings::SampleFormatChoice();
860 if (lCaptureChannels == 0)
861 lCaptureChannels = AudioIORecordChannels.Read();
862
863 // Find out how much free space we have on disk
864 wxLongLong lFreeSpace = ProjectFileIO::Get( project ).GetFreeDiskSpace();
865 if (lFreeSpace < 0) {
866 return 0;
867 }
868
869 // Calculate the remaining time
870 double dRecTime = 0.0;
871 double bytesOnDiskPerSample = SAMPLE_SIZE_DISK(oCaptureFormat);
872 dRecTime = lFreeSpace.GetHi() * 4294967296.0 + lFreeSpace.GetLo();
873 dRecTime /= bytesOnDiskPerSample;
874 dRecTime /= lCaptureChannels;
875 dRecTime /= ProjectRate::Get( project ).GetRate();
876
877 // Convert to minutes before returning
878 int iRecMins = (int)round(dRecTime / 60.0);
879 return iRecMins;
880}
IntSetting AudioIORecordChannels
#define SAMPLE_SIZE_DISK(SampleFormat)
Return the size on disk of one uncompressed sample (bytes)
Definition: SampleFormat.h:67
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:207
PROJECT_RATE_API sampleFormat SampleFormatChoice()
fastfloat_really_inline void round(adjusted_mantissa &am, callback cb) noexcept
Definition: fast_float.h:2512

References AudioIORecordChannels, ProjectFileIO::Get(), ProjectRate::Get(), ProjectFileIO::GetFreeDiskSpace(), ProjectRate::GetRate(), mProject, project, 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 833 of file ProjectManager.cpp.

834{
835 if (iMinutes < 1)
836 // Less than a minute...
837 return XO("Less than 1 minute");
838
839 // Calculate
840 int iHours = iMinutes / 60;
841 int iMins = iMinutes % 60;
842
843 auto sHours = XP( "%d hour", "%d hours", 0 )( iHours );
844
845 auto sMins = XP( "%d minute", "%d minutes", 0 )( iMins );
846
847 /* i18n-hint: A time in hours and minutes. Only translate the "and". */
848 return XO("%s and %s.").Format( sHours, sMins );
849}
XO("Cut/Copy/Paste")
#define XP(sing, plur, n)
Definition: Internat.h:94

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 303 of file ProjectManager.cpp.

304{
305 wxRect wndRect;
306 bool bMaximized = false;
307 bool bIconized = false;
308 GetNextWindowPlacement(&wndRect, &bMaximized, &bIconized);
309
310 // Create and show a NEW project
311 // Use a non-default deleter in the smart pointer!
312 auto sp = AudacityProject::Create();
313 AllProjects{}.Add( sp );
314 auto p = sp.get();
315 auto &project = *p;
316 auto &projectHistory = ProjectHistory::Get( project );
317 auto &projectManager = Get( project );
318 auto &window = ProjectWindow::Get( *p );
319
320 // Issue #2569
321 // There is a dependency on the order of initialisation.
322 // The menus must be created, and registered, before
323 // InitProjectWindows can UpdateMenus.
325
326 InitProjectWindow( window );
327
328 // wxGTK3 seems to need to require creating the window using default position
329 // and then manually positioning it.
330 window.SetPosition(wndRect.GetPosition());
331
332 auto &projectFileManager = ProjectFileManager::Get( *p );
333
334 // This may report an error.
335 projectFileManager.OpenNewProject();
336
337 projectHistory.InitialState();
338 projectManager.RestartTimer();
339
340 if(bMaximized) {
341 window.Maximize(true);
342 }
343 else if (bIconized) {
344 // if the user close down and iconized state we could start back up and iconized state
345 // window.Iconize(TRUE);
346 }
347
348 //Initialise the Listeners
349 auto gAudioIO = AudioIO::Get();
350 gAudioIO->SetListener(
351 ProjectAudioManager::Get( project ).shared_from_this() );
352
353 //Set the NEW project as active:
355
356 // Okay, GetActiveProject() is ready. Now we can get its CommandManager,
357 // and add the shortcut keys to the tooltips.
359
361
362 window.Show(true);
363
364 return p;
365}
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:126
void CreateMenusAndCommands()
static MenuCreator & Get(AudacityProject &project)
Definition: MenuCreator.cpp:91
static ModuleManager & Get()
int Dispatch(ModuleDispatchTypes type)
static ProjectAudioManager & Get(AudacityProject &project)
static ProjectFileManager & Get(AudacityProject &project)
static ProjectHistory & Get(AudacityProject &project)
static ToolManager & Get(AudacityProject &project)
void RegenerateTooltips()

References AllProjects::Add(), AudacityProject::Create(), MenuCreator::CreateMenusAndCommands(), ModuleManager::Dispatch(), AudioIO::Get(), ModuleManager::Get(), ProjectHistory::Get(), MenuCreator::Get(), ProjectAudioManager::Get(), ProjectFileManager::Get(), Get(), ProjectWindow::Get(), ToolManager::Get(), GetNextWindowPlacement(), InitProjectWindow(), project, ProjectInitialized, ToolManager::RegenerateTooltips(), and SetActiveProject().

Referenced by AudacityApp::InitPart2(), AudacityApp::MacNewFile(), OnCloseWindow(), AudacityApp::OnMenuNew(), anonymous_namespace{FileMenus.cpp}::OnNew(), audacity::cloud::audiocom::sync::OpenProjectFromCloud(), 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 380 of file ProjectManager.cpp.

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

References AudacityMessageBox(), AllProjects::begin(), ToolManager::Destroy(), WaveTrackFactory::Destroy(), AdornedRulerPanel::Destroy(), TrackPanel::Destroy(), ModuleManager::Dispatch(), AllProjects::empty(), AudioIO::Get(), ModuleManager::Get(), Clipboard::Get(), ProjectAudioIO::Get(), ProjectFileIO::Get(), ProjectHistory::Get(), UndoManager::Get(), TrackList::Get(), Viewport::Get(), ProjectAudioManager::Get(), ProjectFileManager::Get(), ProjectSettings::Get(), ProjectWindow::Get(), ToolManager::Get(), GetActiveProject(), anonymous_namespace{TrackSelectHandle.cpp}::Message(), mProject, mTimer, New(), ProjectFileIOExtensionRegistry::OnClose(), project, ProjectClosing, AllProjects::Remove(), SaveWindowSize(), sbClosingAll, sbSkipPromptingForSave, sbWindowRectAlreadySaved, SetActiveProject(), ProjectHistory::SetStateTo(), settings(), AllProjects::size(), TitleRestorer::sProjName, TitleRestorer::sProjNumber, ProjectAudioManager::Stop(), tracks, Veto, 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 367 of file ProjectManager.cpp.

368{
370 ProjectWindow::Get(mProject).Close(true);
371}

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 790 of file ProjectManager.cpp.

791{
792 auto &project = mProject;
793
794 // Be careful to null-check the window. We might get to this function
795 // during shut-down, but a timer hasn't been told to stop sending its
796 // messages yet.
797 auto pWindow = ProjectWindow::Find( &project );
798 if ( !pWindow )
799 return;
800 auto &window = *pWindow;
801
802 window.UpdateStatusWidths();
803
804 const auto &msg = ProjectStatus::Get( project ).Get( field );
805 SetStatusText( msg, field );
806
807 if ( field == MainStatusBarField() )
808 // When recording, let the NEW status message stay at least as long as
809 // the timer interval (if it is not replaced again by this function),
810 // before replacing it with the message about remaining disk capacity.
811 RestartTimer();
812}
#define field(n, t)
Definition: ImportAUP.cpp:165
StatusBarField MainStatusBarField()
ID of the second field in the status bar. This field is expandable.
void SetStatusText(const TranslatableString &text, const StatusBarField &field)
static ProjectWindow * Find(AudacityProject *pProject)

References field, ProjectWindow::Find(), ProjectStatus::Get(), MainStatusBarField(), mProject, project, 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 760 of file ProjectManager.cpp.

761{
762 auto &project = mProject;
763 auto &projectAudioIO = ProjectAudioIO::Get( project );
764 auto meterToolBars = MeterToolBar::GetToolBars( project );
765
766 for (auto& meterToolBar : meterToolBars)
767 meterToolBar.get().UpdateControls();
768
769 auto gAudioIO = AudioIO::Get();
770 // gAudioIO->GetNumCaptureChannels() should only be positive
771 // when we are recording.
772 if (projectAudioIO.GetAudioIOToken() > 0 && gAudioIO->GetNumCaptureChannels() > 0) {
773 wxLongLong freeSpace = ProjectFileIO::Get(project).GetFreeDiskSpace();
774 if (freeSpace >= 0) {
775
776 int iRecordingMins = GetEstimatedRecordingMinsLeftOnDisk(gAudioIO->GetNumCaptureChannels());
777 auto sMessage = XO("Disk space remaining for recording: %s")
778 .Format( GetHoursMinsString(iRecordingMins) );
779
780 // Do not change mLastMainStatusMessage
782 }
783 }
784
785 // As also with the TrackPanel timer: wxTimer may be unreliable without
786 // some restarts
787 RestartTimer();
788}
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, project, RestartTimer(), SetStatusText(), and XO().

Here is the call graph for this function:

◆ OpenFiles()

void ProjectManager::OpenFiles ( AudacityProject proj)
static

Definition at line 626 of file ProjectManager.cpp.

627{
628 auto selectedFiles =
629 ProjectFileManager::ShowOpenDialog(FileNames::Operation::Open);
630 if (selectedFiles.size() == 0) {
632 return;
633 }
634
635 //first sort selectedFiles.
636 selectedFiles.Sort(FileNames::CompareNoCase);
637
638 auto cleanup = finally( [] {
640 } );
641
642 for (const auto &fileName : selectedFiles) {
643 // Make sure it isn't already open.
645 continue; // Skip ones that are already open.
646
647 proj = OpenProject( proj, fileName,
648 true /* addtohistory */, false /* reuseNonemptyProject */ );
649 }
650}
static void SetLastOpenType(const FileNames::FileType &type)
Definition: Import.cpp:254
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 709 of file ProjectManager.cpp.

712{
713 ProjectManager::ProjectChooser chooser{ pGivenProject, reuseNonemptyProject };
714 if (auto pProject = ProjectFileManager::OpenFile(
715 std::ref(chooser), fileNameArg, addtohistory )) {
716 chooser.Commit();
717
718 auto &projectFileIO = ProjectFileIO::Get( *pProject );
719 if( projectFileIO.IsRecovered() ) {
720 auto &viewport = Viewport::Get(*pProject);
721 viewport.Zoom(viewport.GetZoomOfToFit());
722 // "Project was recovered" replaces "Create new project" in Undo History.
723 auto &undoManager = UndoManager::Get( *pProject );
724 undoManager.RemoveStates(0, 1);
725 }
726 return pProject;
727 }
728 return nullptr;
729}
static AudacityProject * OpenFile(const ProjectChooserFn &chooser, const FilePath &fileName, bool addtohistory=true)
Callable object that supplies the chooser argument of ProjectFileManager::OpenFile.

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

Referenced by EVT_MENU_RANGE(), LOFImportFileHandle::lofOpenFiles(), OpenFiles(), audacity::cloud::audiocom::sync::OpenProjectFromCloud(), and RecoverAllProjects().

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

◆ operator=()

ProjectManager & ProjectManager::operator= ( const ProjectManager )
delete

◆ ResetProjectToEmpty()

void ProjectManager::ResetProjectToEmpty ( )

Definition at line 732 of file ProjectManager.cpp.

732 {
733 auto &project = mProject;
734 auto &projectFileIO = ProjectFileIO::Get( project );
735 auto &projectFileManager = ProjectFileManager::Get( project );
736 auto &projectHistory = ProjectHistory::Get( project );
737 auto &viewInfo = ViewInfo::Get( project );
738
741
743
744 // InitialState will reset UndoManager
745 projectHistory.InitialState();
746 projectHistory.SetDirty(false);
747
748 projectFileManager.CloseProject();
749 projectFileManager.OpenProject();
750}
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
static WaveTrackFactory & Reset(AudacityProject &project)
Definition: WaveTrack.cpp:3386
void DoSelectAll(AudacityProject &project)
AUDACITY_DLL_API void DoRemoveTracks(AudacityProject &)

References TrackUtilities::DoRemoveTracks(), SelectUtilities::DoSelectAll(), ProjectFileIO::Get(), ProjectHistory::Get(), ViewInfo::Get(), ProjectFileManager::Get(), mProject, project, 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 752 of file ProjectManager.cpp.

753{
754 if (mTimer) {
755 // mTimer->Stop(); // not really needed
756 mTimer->Start( 3000 ); // Update messages as needed once every 3 s.
757 }
758}

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 652 of file ProjectManager.cpp.

653{
654 // DMM: If the project is dirty, that means it's been touched at
655 // all, and it's not safe to open a fresh project directly in its
656 // place. Only if the project is brandnew clean and the user
657 // hasn't done any action at all is it safe for Open to take place
658 // inside the current project.
659 //
660 // If you try to Open a fresh project inside the current window when
661 // there are no tracks, but there's an Undo history, etc, then
662 // bad things can happen, including orphan blocks, or tracks
663 // referring to non-existent blocks
664 if (
665 ProjectHistory::Get( proj ).GetDirty() ||
666 !TrackList::Get( proj ).empty()
667 )
668 return false;
669 // This project is clean; it's never been touched. Therefore
670 // all relevant member variables are in their initial state,
671 // and it's okay to open a NEW project inside its window.
672 return true;
673}

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 110 of file ProjectManager.cpp.

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

376{
377 sbClosingAll = closing;
378}

References sbClosingAll.

Referenced by CloseAllProjects().

Here is the caller graph for this function:

◆ SetSkipSavePrompt()

void ProjectManager::SetSkipSavePrompt ( bool  bSkip)
inline

Definition at line 115 of file ProjectManager.h.

115{ sbSkipPromptingForSave = bSkip; };

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

Here is the caller graph for this function:

◆ SetStatusText() [1/2]

void ProjectManager::SetStatusText ( const TranslatableString text,
const StatusBarField field 
)

Definition at line 814 of file ProjectManager.cpp.

816{
818
819 if (index >= 0)
820 SetStatusText(text, index);
821}
static int GetFieldIndex(const AudacityProject &project, const StatusBarField &identifier)
Returns the zero based index of the field or -1 if field is not present.

References field, ProjectStatusFieldsRegistry::GetFieldIndex(), mProject, and SetStatusText().

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

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

◆ SetStatusText() [2/2]

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

Definition at line 823 of file ProjectManager.cpp.

824{
825 auto &project = mProject;
826 auto pWindow = ProjectWindow::Find( &project );
827 if ( !pWindow )
828 return;
829 auto &window = *pWindow;
830 window.GetStatusBar()->SetStatusText(text.Translation(), number);
831}
wxString Translation() const

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

Here is the call graph for this function:

Member Data Documentation

◆ mProject

AudacityProject& ProjectManager::mProject
private

◆ mProjectFileIOSubscription

Observer::Subscription ProjectManager::mProjectFileIOSubscription
private

Definition at line 133 of file ProjectManager.h.

Referenced by ProjectManager().

◆ mProjectStatusSubscription

Observer::Subscription ProjectManager::mProjectStatusSubscription
private

Definition at line 132 of file ProjectManager.h.

Referenced by ProjectManager().

◆ mTimer

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

Definition at line 130 of file ProjectManager.h.

Referenced by OnCloseWindow(), and RestartTimer().

◆ sbSkipPromptingForSave

bool ProjectManager::sbSkipPromptingForSave = false
staticprivate

Definition at line 138 of file ProjectManager.h.

Referenced by OnCloseWindow().

◆ sbWindowRectAlreadySaved

bool ProjectManager::sbWindowRectAlreadySaved = false
staticprivate

Definition at line 137 of file ProjectManager.h.

Referenced by OnCloseWindow().


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