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

854 {
855 auto &project = mProject;
856
857 // Obtain the current settings
858 auto oCaptureFormat = QualitySettings::SampleFormatChoice();
859 if (lCaptureChannels == 0)
860 lCaptureChannels = AudioIORecordChannels.Read();
861
862 // Find out how much free space we have on disk
863 wxLongLong lFreeSpace = ProjectFileIO::Get( project ).GetFreeDiskSpace();
864 if (lFreeSpace < 0) {
865 return 0;
866 }
867
868 // Calculate the remaining time
869 double dRecTime = 0.0;
870 double bytesOnDiskPerSample = SAMPLE_SIZE_DISK(oCaptureFormat);
871 dRecTime = lFreeSpace.GetHi() * 4294967296.0 + lFreeSpace.GetLo();
872 dRecTime /= bytesOnDiskPerSample;
873 dRecTime /= lCaptureChannels;
874 dRecTime /= ProjectRate::Get( project ).GetRate();
875
876 // Convert to minutes before returning
877 int iRecMins = (int)round(dRecTime / 60.0);
878 return iRecMins;
879}
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 832 of file ProjectManager.cpp.

833{
834 if (iMinutes < 1)
835 // Less than a minute...
836 return XO("Less than 1 minute");
837
838 // Calculate
839 int iHours = iMinutes / 60;
840 int iMins = iMinutes % 60;
841
842 auto sHours = XP( "%d hour", "%d hours", 0 )( iHours );
843
844 auto sMins = XP( "%d minute", "%d minutes", 0 )( iMins );
845
846 /* i18n-hint: A time in hours and minutes. Only translate the "and". */
847 return XO("%s and %s.").Format( sHours, sMins );
848}
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 && (settings.EmptyCanBeDirty() || 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 if( !bHasTracks )
444 {
445 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.");
446 }
447 int result = AudacityMessageBox(
448 Message,
449 Title,
450 wxYES_NO | wxCANCEL | wxICON_QUESTION,
451 &window);
452
453 if (result == wxCANCEL || (result == wxYES &&
454 !GuardedCall<bool>( [&]{ return projectFileManager.Save(); } )
455 )) {
456 event.Veto();
457 return;
458 }
459 }
460 }
461
462 // Ask extensions if they allow the project to be closed
464 && event.CanVeto())
465 {
466 event.Veto();
467 return;
468 }
469
470#ifdef __WXMAC__
471 // Fix bug apparently introduced into 2.1.2 because of wxWidgets 3:
472 // closing a project that was made full-screen (as by clicking the green dot
473 // or command+/; not merely "maximized" as by clicking the title bar or
474 // Zoom in the Window menu) leaves the screen black.
475 // Fix it by un-full-screening.
476 // (But is there a different way to do this? What do other applications do?
477 // I don't see full screen windows of Safari shrinking, but I do see
478 // momentary blackness.)
479 window.ShowFullScreen(false);
480#endif
481
482 // This achieves auto save on close of project before other important
483 // project state is destroyed
484 window.Publish(ProjectWindowDestroyedMessage {});
486
487 // Stop the timer since there's no need to update anything anymore
488 mTimer.reset();
489
490 // DMM: Save the size of the last window the user closes
491 //
492 // LL: Save before doing anything else to the window that might make
493 // its size change.
495
496 window.SetIsBeingDeleted();
497
498 // Mac: we never quit as the result of a close.
499 // Other systems: we quit only when the close is the result of an external
500 // command (on Windows, those are taskbar closes, "X" box, Alt+F4, etc.)
501 bool quitOnClose;
502#ifdef __WXMAC__
503 quitOnClose = false;
504#else
505 quitOnClose = !projectFileManager.GetMenuClose();
506#endif
507
508 // DanH: If we're definitely about to quit, clear the clipboard.
509 auto &clipboard = Clipboard::Get();
510 if ((AllProjects{}.size() == 1) &&
511 (quitOnClose || sbClosingAll))
512 clipboard.Clear();
513 else {
514 auto clipboardProject = clipboard.Project().lock();
515 if ( clipboardProject.get() == &mProject ) {
516 // Closing the project from which content was cut or copied.
517 // For 3.0.0, clear the clipboard, because accessing clipboard contents
518 // would depend on a database connection to the closing project, but
519 // that connection should closed now so that the project file can be
520 // freely moved.
521 // Notes:
522 // 1) maybe clipboard contents could be saved by migrating them to
523 // another temporary database, but that extra effort is beyond the
524 // scope of 3.0.0.
525 // 2) strictly speaking this is necessary only when the clipboard
526 // contains WaveTracks.
527 clipboard.Clear();
528 }
529 }
530
531 // JKC: For Win98 and Linux do not detach the menu bar.
532 // We want wxWidgets to clean it up for us.
533 // TODO: Is there a Mac issue here??
534 // SetMenuBar(NULL);
535
536 // Compact the project.
537 projectFileManager.CompactProjectOnClose();
538
539 // Set (or not) the bypass flag to indicate that deletes that would happen during
540 // the UndoManager::ClearStates() below are not necessary.
541 projectFileIO.SetBypass();
542
543 {
544 // This can reduce reference counts of sample blocks in the project's
545 // tracks.
547
548 // Delete all the tracks to free up memory
549 tracks.Clear();
550 }
551
552 // Some of the AdornedRulerPanel functions refer to the TrackPanel, so destroy this
553 // before the TrackPanel is destroyed. This change was needed to stop Audacity
554 // crashing when running with Jaws on Windows 10 1703.
556
557 // Destroy the TrackPanel early so it's not around once we start
558 // deleting things like tracks and such out from underneath it.
559 // Check validity of mTrackPanel per bug 584 Comment 1.
560 // Deeper fix is in the Import code, but this failsafes against crash.
562 // Finalize the tool manager before the children since it needs
563 // to save the state of the toolbars.
565
566 window.DestroyChildren();
567
568 // Close project only now, because TrackPanel might have been holding
569 // some shared_ptr to WaveTracks keeping SampleBlocks alive.
570 // We're all done with the project file, so close it now
571 projectFileManager.CloseProject();
572
574
575 // Remove self from the global array, but defer destruction of self
576 auto pSelf = AllProjects{}.Remove( project );
577 wxASSERT( pSelf );
578
579 if (GetActiveProject().lock().get() == &project) {
580 // Find a NEW active project
581 if ( !AllProjects{}.empty() ) {
583 }
584 else {
585 SetActiveProject(nullptr);
586 }
587 }
588
589 // Since we're going to be destroyed, make sure we're not to
590 // receive audio notifications anymore.
591 // PRL: Maybe all this is unnecessary now that the listener is managed
592 // by a weak pointer.
593 if ( gAudioIO->GetListener().get() == &ProjectAudioManager::Get( project ) ) {
594 auto active = GetActiveProject().lock();
595 gAudioIO->SetListener(
596 active
597 ? ProjectAudioManager::Get( *active ).shared_from_this()
598 : nullptr
599 );
600 }
601
602 if (AllProjects{}.empty() && !sbClosingAll) {
603
604#if !defined(__WXMAC__)
605 if (quitOnClose) {
606 // Simulate the application Exit menu item
607 wxCommandEvent evt{ wxEVT_MENU, wxID_EXIT };
608 wxTheApp->AddPendingEvent( evt );
609 }
610 else {
612 // For non-Mac, always keep at least one project window open
613 (void) New();
614 }
615#endif
616 }
617
618 window.Destroy();
619
620 // Destroys this
621 pSelf.reset();
622}
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:69
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:314
static void Destroy(AudacityProject &project)
Definition: TrackPanel.cpp:244
void ClearStates()
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:3366
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(), UndoManager::ClearStates(), ToolManager::Destroy(), WaveTrackFactory::Destroy(), AdornedRulerPanel::Destroy(), TrackPanel::Destroy(), ModuleManager::Dispatch(), AllProjects::empty(), AudioIO::Get(), ModuleManager::Get(), Clipboard::Get(), ProjectAudioIO::Get(), ProjectFileIO::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(), 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 789 of file ProjectManager.cpp.

790{
791 auto &project = mProject;
792
793 // Be careful to null-check the window. We might get to this function
794 // during shut-down, but a timer hasn't been told to stop sending its
795 // messages yet.
796 auto pWindow = ProjectWindow::Find( &project );
797 if ( !pWindow )
798 return;
799 auto &window = *pWindow;
800
801 window.UpdateStatusWidths();
802
803 const auto &msg = ProjectStatus::Get( project ).Get( field );
804 SetStatusText( msg, field );
805
806 if ( field == MainStatusBarField() )
807 // When recording, let the NEW status message stay at least as long as
808 // the timer interval (if it is not replaced again by this function),
809 // before replacing it with the message about remaining disk capacity.
810 RestartTimer();
811}
#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 759 of file ProjectManager.cpp.

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

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

711{
712 ProjectManager::ProjectChooser chooser{ pGivenProject, reuseNonemptyProject };
713 if (auto pProject = ProjectFileManager::OpenFile(
714 std::ref(chooser), fileNameArg, addtohistory )) {
715 chooser.Commit();
716
717 auto &projectFileIO = ProjectFileIO::Get( *pProject );
718 if( projectFileIO.IsRecovered() ) {
719 auto &viewport = Viewport::Get(*pProject);
720 viewport.Zoom(viewport.GetZoomOfToFit());
721 // "Project was recovered" replaces "Create new project" in Undo History.
722 auto &undoManager = UndoManager::Get( *pProject );
723 undoManager.RemoveStates(0, 1);
724 }
725 return pProject;
726 }
727 return nullptr;
728}
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 731 of file ProjectManager.cpp.

731 {
732 auto &project = mProject;
733 auto &projectFileIO = ProjectFileIO::Get( project );
734 auto &projectFileManager = ProjectFileManager::Get( project );
735 auto &projectHistory = ProjectHistory::Get( project );
736 auto &viewInfo = ViewInfo::Get( project );
737
740
742
743 // InitialState will reset UndoManager
744 projectHistory.InitialState();
745 projectHistory.SetDirty(false);
746
747 projectFileManager.CloseProject();
748 projectFileManager.OpenProject();
749}
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
static WaveTrackFactory & Reset(AudacityProject &project)
Definition: WaveTrack.cpp:3359
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 751 of file ProjectManager.cpp.

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

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

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

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

815{
817
818 if (index >= 0)
819 SetStatusText(text, index);
820}
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 822 of file ProjectManager.cpp.

823{
824 auto &project = mProject;
825 auto pWindow = ProjectWindow::Find( &project );
826 if ( !pWindow )
827 return;
828 auto &window = *pWindow;
829 window.GetStatusBar()->SetStatusText(text.Translation(), number);
830}
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: