53#include <wx/scrolbar.h>
55#include <wx/splitter.h>
58#include "../images/AudacityLogoAlpha.xpm"
63 bool isMaximized,
bool isIconized) {
81 return std::make_shared< ProjectManager >( project );
118 if (sbWindowRectAlreadySaved)
122 bool validWindowForSaveWindowSize = FALSE;
124 bool foundIconizedProject = FALSE;
128 if (!window.IsIconized()) {
129 validWindowForSaveWindowSize = TRUE;
130 validProject = &window;
134 foundIconizedProject = TRUE;
137 if (validWindowForSaveWindowSize)
139 wxRect windowRect = validProject->GetRect();
141 bool wndMaximized = validProject->IsMaximized();
147 if (foundIconizedProject) {
149 bool wndMaximized = validProject->IsMaximized();
165 sbWindowRectAlreadySaved =
true;
173 auto &project = *pProject;
175#ifdef EXPERIMENTAL_DA2
185 auto statusBar = window.CreateStatusBar(4);
186#if wxUSE_ACCESSIBILITY
190 statusBar->SetName(
wxT(
"status_line"));
217 auto ubs = std::make_unique<wxBoxSizer>(wxVERTICAL);
218 ubs->Add(
ToolManager::Get( project ).GetTopDock(), 0, wxEXPAND | wxALIGN_TOP );
219 topPanel->SetSizer(ubs.release());
224 auto ubs = std::make_unique<wxBoxSizer>(wxVERTICAL);
226 bs->Add(topPanel, 0, wxEXPAND | wxALIGN_TOP);
229 window.SetAutoLayout(
true);
230 window.SetSizer(ubs.release());
250 bs =
static_cast<wxBoxSizer*
>(trackListWindow->GetSizer());
257 auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
260 hs->Add(&trackPanel, 1, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP);
264 auto vs = std::make_unique<wxBoxSizer>(wxVERTICAL);
267 vs->Add(vsBar, 1, wxEXPAND | wxALIGN_TOP);
268 hs->Add(vs.release(), 0, wxEXPAND | wxALIGN_TOP);
271 bs->Add(&
ruler, 0, wxEXPAND | wxALIGN_TOP);
272 bs->Add(hs.release(), 1, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP);
277 auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
280 hs->Add(viewInfo.GetLeftOffset() - 1, 0);
281 hs->Add(hsBar, 1, wxALIGN_BOTTOM);
282 hs->Add(vsBar->GetSize().GetWidth(), 0);
283 bs->Add(hs.release(), 0, wxEXPAND | wxALIGN_LEFT);
287 trackListWindow->SetAutoLayout(
true);
288 trackListWindow->Layout();
290 wxASSERT( trackPanel.GetProject() == &project );
293 trackPanel.SetFocus();
296 ruler.SetLeftOffset(viewInfo.GetLeftOffset());
303#if !defined(__WXMAC__) && !defined(__WXX11__)
305#if defined(__WXMSW__)
306 wxIcon ic{ wxICON(AudacityLogo) };
307#elif defined(__WXGTK__)
308 wxIcon ic{wxICON(AudacityLogoAlpha)};
318 auto msg =
XO(
"Welcome to Audacity version %s")
319 .Format( AUDACITY_VERSION_STRING );
322#ifdef EXPERIMENTAL_DA2
330 bool bMaximized =
false;
331 bool bIconized =
false;
341 auto &projectManager =
Get( project );
354 window.SetPosition(wndRect.GetPosition());
359 projectFileManager.OpenNewProject();
361 projectHistory.InitialState();
362 projectManager.RestartTimer();
365 window.Maximize(
true);
367 else if (bIconized) {
374 gAudioIO->SetListener(
378#ifdef EXPERIMENTAL_SPECTRAL_EDITING
426 if (window.IsBeingDeleted())
432 if (event.CanVeto() && (::wxIsBusy() || project.mbBusyImporting))
445 if (projectAudioIO.GetAudioIOToken()>0 &&
446 gAudioIO->IsStreamActive(projectAudioIO.GetAudioIOToken())) {
451 projectAudioIO.SetAudioIOToken(0);
452 window.RedrawProject();
454 else if (gAudioIO->IsMonitoring()) {
455 gAudioIO->StopStream();
459 bool bHasTracks = !tracks.empty();
465 && (
settings.EmptyCanBeDirty() || bHasTracks)) {
469 auto Title =
XO(
"%sSave changes to %s?")
471 auto Message =
XO(
"Save project before closing?");
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.");
479 wxYES_NO | wxCANCEL | wxICON_QUESTION,
482 if (result == wxCANCEL || (result == wxYES &&
483 !GuardedCall<bool>( [&]{
return projectFileManager.Save(); } )
499 window.ShowFullScreen(
false);
516 window.SetIsBeingDeleted();
525 quitOnClose = !projectFileManager.GetMenuClose();
534 auto clipboardProject = clipboard.Project().lock();
535 if ( clipboardProject.get() == &
mProject ) {
557 projectFileManager.CompactProjectOnClose();
561 projectFileIO.SetBypass();
586 window.DestroyChildren();
591 projectFileManager.CloseProject();
615 gAudioIO->SetListener(
624#if !defined(__WXMAC__)
627 wxCommandEvent evt{ wxEVT_MENU, wxID_EXIT };
628 wxTheApp->AddPendingEvent( evt );
649 if (selectedFiles.size() == 0) {
657 auto cleanup =
finally( [] {
661 for (
const auto &fileName : selectedFiles) {
711 if (mpGivenProject) {
716 bool checkReuse = (openingProjectFile || !mReuseNonemptyProject);
718 return *(mpUsedProject = mpGivenProject);
720 return *(mpUsedProject =
New());
725 mpUsedProject =
nullptr;
730 bool addtohistory,
bool reuseNonemptyProject)
734 std::ref(chooser), fileNameArg, addtohistory )) {
738 if( projectFileIO.IsRecovered() ) {
740 window.Zoom( window.GetZoomOfToFit() );
743 undoManager.RemoveStates(0, 1);
764 projectHistory.InitialState();
765 projectHistory.SetDirty(
false);
767 projectFileManager.CloseProject();
768 projectFileManager.OpenProject();
785 for (
auto& meterToolBar : meterToolBars)
786 meterToolBar.get().UpdateControls();
791 if (projectAudioIO.GetAudioIOToken() > 0 && gAudioIO->GetNumCaptureChannels() > 0) {
793 if (freeSpace >= 0) {
796 auto sMessage =
XO(
"Disk space remaining for recording: %s")
819 auto &window = *pWindow;
821 window.UpdateStatusWidths();
839 auto &window = *pWindow;
840 window.GetStatusBar()->SetStatusText(text.
Translation(), number);
847 return XO(
"Less than 1 minute");
850 int iHours = iMinutes / 60;
851 int iMins = iMinutes % 60;
853 auto sHours =
XP(
"%d hour",
"%d hours", 0 )( iHours );
855 auto sMins =
XP(
"%d minute",
"%d minutes", 0 )( iMins );
858 return XO(
"%s and %s.").Format( sHours, sMins );
870 if (lCaptureChannels == 0)
875 if (lFreeSpace < 0) {
880 double dRecTime = 0.0;
882 dRecTime = lFreeSpace.GetHi() * 4294967296.0 + lFreeSpace.GetLo();
883 dRecTime /= bytesOnDiskPerSample;
884 dRecTime /= lCaptureChannels;
888 int iRecMins = (int)
round(dRecTime / 60.0);
AUDACITY_DLL_API std::weak_ptr< AudacityProject > GetActiveProject()
void SetActiveProject(AudacityProject *project)
Handle changing of active project and keep global project pointer.
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
IntSetting AudioIORecordChannels
#define XP(sing, plur, n)
ProjectFileIOMessage
Subscribe to ProjectFileIO to receive messages; always in idle time.
void InitProjectWindow(ProjectWindow &window)
static AudacityProject::AttachedObjects::RegisteredFactory sProjectManagerKey
const int AudacityProjectTimerID
an object holding per-project preferred sample rate
IntSetting ProjectWindowY
IntSetting ProjectWindowX
void GetDefaultWindowRect(wxRect *defRect)
IntSetting ProjectWindowWidth
BoolSetting ProjectWindowIconized
BoolSetting ProjectWindowMaximized
IntSetting ProjectWindowNormalHeight
IntSetting ProjectWindowHeight
IntSetting ProjectWindowNormalX
void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized)
IntSetting ProjectWindowNormalWidth
IntSetting ProjectWindowNormalY
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
accessors for certain important windows associated with each project
static Settings & settings()
static AdornedRulerPanel & Get(AudacityProject &project)
static void Destroy(AudacityProject &project)
void Add(const value_type &pProject)
This invalidates iterators.
value_type Remove(AudacityProject &project)
const_iterator begin() const
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static std::shared_ptr< AudacityProject > Create()
Use this factory function.
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
static void SetLastOpenType(const FileNames::FileType &type)
static ModuleManager & Get()
int Dispatch(ModuleDispatchTypes type)
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
static ProjectAudioIO & Get(AudacityProject &project)
void Stop(bool stopStream=true)
static ProjectAudioManager & Get(AudacityProject &project)
static ProjectFileIO & Get(AudacityProject &project)
wxLongLong GetFreeDiskSpace() const
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 * OpenFile(const ProjectChooserFn &chooser, const FilePath &fileName, bool addtohistory=true)
static ProjectFileManager & Get(AudacityProject &project)
static ProjectHistory & Get(AudacityProject &project)
Callable object that supplies the chooser argument of ProjectFileManager::OpenFile.
AudacityProject * mpGivenProject
AudacityProject & operator()(bool openingProjectFile)
May create a fresh project.
AudacityProject * mpUsedProject
~ProjectChooser()
Destroy any fresh project, or rollback the existing project, unless committed.
void Commit()
Commit the creation of any fresh project or changes to the existing project.
Object associated with a project for high-level management of the project's lifetime,...
static bool sbWindowRectAlreadySaved
static ProjectManager & Get(AudacityProject &project)
void OnStatusChange(StatusBarField field)
void OnCloseWindow(wxCloseEvent &event)
static bool sbSkipPromptingForSave
static AudacityProject * New()
TranslatableString GetHoursMinsString(int iMinutes)
std::unique_ptr< wxTimer > mTimer
void OnTimer(wxTimerEvent &event)
static void SaveWindowSize()
static void OpenFiles(AudacityProject *proj)
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.
static void SetClosingAll(bool closing)
Observer::Subscription mProjectFileIOSubscription
~ProjectManager() override
ProjectManager(AudacityProject &project)
AudacityProject & mProject
static bool SafeToOpenProjectInto(AudacityProject &proj)
False when it is unsafe to overwrite proj with contents of an .aup3 file.
Observer::Subscription mProjectStatusSubscription
void OnReconnectionFailure(ProjectFileIOMessage)
void SetStatusText(const TranslatableString &text, int number)
int GetEstimatedRecordingMinsLeftOnDisk(long lCaptureChannels=0)
void ResetProjectToEmpty()
static ProjectRate & Get(AudacityProject &project)
static ProjectSelectionManager & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
static ProjectStatus & Get(AudacityProject &project)
std::shared_ptr< AudacityProject > FindProject()
A top-level window associated with a project, and handling scrollbars and zooming.
wxScrollBar & GetHorizontalScrollBar()
static ProjectWindow & Get(AudacityProject &project)
wxScrollBar & GetVerticalScrollBar()
wxPanel * GetTopPanel() noexcept
Top panel contains project-related controls and tools.
static ProjectWindow * Find(AudacityProject *pProject)
wxRect GetNormalizedWindowState() const
wxWindow * GetTrackListWindow() noexcept
Track list window is the parent container for TrackPanel.
wxSplitterWindow * GetContainerWindow() noexcept
Container is a parent window for both effects panel and track list windows.
void UpdateStatusWidths()
void SetListener(SelectionBarListener *l)
static SelectionBar & Get(AudacityProject &project)
bool Write(const T &value)
Write value to config and return true if successful.
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined */
static SpectralSelectionBar & Get(AudacityProject &project)
void SetListener(SpectralSelectionBarListener *l)
wxColour & Colour(int iIndex)
wxBitmap & Bitmap(int iIndex)
static TrackList & Get(AudacityProject &project)
static TrackPanel & Get(AudacityProject &project)
static void Destroy(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
static UndoManager & Get(AudacityProject &project)
static ViewInfo & Get(AudacityProject &project)
static void Destroy(AudacityProject &project)
static WaveTrackFactory & Reset(AudacityProject &project)
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
FILES_API int CompareNoCase(const wxString &first, const wxString &second)
PROJECT_RATE_API sampleFormat SampleFormatChoice()
void DoSelectAll(AudacityProject &project)
void DoRemoveTracks(AudacityProject &project)
void SaveWindowPreferences(const wxRect &windowRect, const wxRect &normalRect, bool isMaximized, bool isIconized)
TranslatableString Message(unsigned trackCount)
fastfloat_really_inline void round(adjusted_mantissa &am, callback cb) noexcept
Message sent when the project window is closed.