From 9cb7e23e05d31c3a3dcb5bdaba04e53a39800f0f Mon Sep 17 00:00:00 2001 From: James Crook Date: Mon, 5 Sep 2016 19:18:54 +0100 Subject: [PATCH 1/2] Bug 322 - "Save Changes?" dialog does not indicate which project is being closed When there is ambiguity about which project is being saved, the project title bars now change to be more informative. --- src/Project.cpp | 95 +++++++++++++++++++++++++++++++++++++++++++------ src/Project.h | 5 ++- 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/src/Project.cpp b/src/Project.cpp index 78f9f24f7..1d4cae218 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -1366,10 +1366,20 @@ wxString AudacityProject::GetName() return name; } -void AudacityProject::SetProjectTitle() +// Pass a number in to show project number, or -1 not to. +void AudacityProject::SetProjectTitle( int number) { wxString name = GetName(); - if( name.IsEmpty() ) + + // If we are showing project numbers, then we also explicitly show "" if there + // is none. + if( number >= 0 ){ + /* i18n-hint: The %02i is the project number, the %s is the project name.*/ + name = wxString::Format( wxT("[Project %02i] Audacity \"%s\""), number+1 , + name.IsEmpty() ? "" : name.c_str() ); + } + // If we are not showing numbers, then shows as 'Audacity'. + else if( name.IsEmpty() ) { name = wxT("Audacity"); } @@ -2001,6 +2011,42 @@ void AudacityProject::HandleResize() UpdateLayout(); } +// What number is this project? +int AudacityProject::GetProjectNumber() +{ + int i; + for(i=0;iGetName().IsEmpty() ) + j++; + } + return j; +} + +void AudacityProject::RefreshAllTitles(bool bShowProjectNumbers ) +{ + int i; + for(i=0;imIconized ){ + gAudacityProjects[i]->SetProjectTitle( bShowProjectNumbers ? i : -1 ); + } + } + } +} + void AudacityProject::OnIconize(wxIconizeEvent &event) { @@ -2317,6 +2363,34 @@ void AudacityProject::OnMouseEvent(wxMouseEvent & event) SetActiveProject(this); } +// TitleRestorer restores project window titles to what they were, in its destructor. +class TitleRestorer{ +public: + TitleRestorer(AudacityProject * p ){ + // Construct this projects name and number. + sProjNumber = ""; + sProjName = p->GetName(); + if (sProjName.IsEmpty()){ + sProjName = _(""); + UnnamedCount=AudacityProject::CountUnnamed(); + if( UnnamedCount > 1 ){ + sProjNumber.Printf( "[Project %02i] ", p->GetProjectNumber()+1 ); + AudacityProject::RefreshAllTitles( true ); + } + } else { + UnnamedCount = 0; + } + }; + ~TitleRestorer() { + if( UnnamedCount > 1 ) + AudacityProject::RefreshAllTitles( false ); + }; + wxString sProjNumber; + wxString sProjName; + int UnnamedCount; +}; + + // LL: All objects that have a reference to the DirManager should // be deleted before the final mDirManager->Deref() in this // routine. Failing to do so can cause unwanted recursion @@ -2379,14 +2453,16 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event) // project is now empty. if (event.CanVeto() && (mEmptyCanBeDirty || bHasTracks)) { if (GetUndoManager()->UnsavedChanges()) { - + TitleRestorer Restorer( this );// RAII + /* i18n-hint: The first %s numbers the project, the second %s is the project name.*/ + wxString Title = wxString::Format(_("%sSave changes to %s?"), Restorer.sProjNumber.c_str(), Restorer.sProjName.c_str()); wxString Message = _("Save changes before closing?"); if( !bHasTracks ) { Message += _("\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."); } int result = wxMessageBox( Message, - _("Save changes?"), + Title, wxYES_NO | wxCANCEL | wxICON_QUESTION, this); @@ -4050,13 +4126,12 @@ bool AudacityProject::SaveAs(const wxString & newFileName, bool bWantSaveCompres return(success); } + bool AudacityProject::SaveAs(bool bWantSaveCompressed /*= false*/) { - wxFileName filename(mFileName); + TitleRestorer Restorer(this); // RAII - wxString sProjName = this->GetName(); - if (sProjName.IsEmpty()) - sProjName = _(""); + wxFileName filename(mFileName); wxString sDialogTitle; if (bWantSaveCompressed) @@ -4073,7 +4148,7 @@ To open a compressed project takes longer than usual, as it imports \n\ each compressed track.\n"), true) != wxID_OK) return false; - sDialogTitle.Printf(_("Save Compressed Project \"%s\" As..."), sProjName.c_str()); + sDialogTitle.Printf(_("%sSave Compressed Project \"%s\" As..."), Restorer.sProjNumber.c_str(),Restorer.sProjName.c_str()); } else { @@ -4083,7 +4158,7 @@ each compressed track.\n"), For an audio file that will open in other apps, use 'Export'.\n"), true) != wxID_OK) return false; - sDialogTitle.Printf(_("Save Project \"%s\" As..."), sProjName.c_str()); + sDialogTitle.Printf(_("%sSave Project \"%s\" As..."), Restorer.sProjNumber.c_str(), Restorer.sProjName.c_str()); } // JKC: I removed 'wxFD_OVERWRITE_PROMPT' because we are checking diff --git a/src/Project.h b/src/Project.h index 922ee445a..48a05c0a8 100644 --- a/src/Project.h +++ b/src/Project.h @@ -257,7 +257,7 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame, const wxString &GetFileName() { return mFileName; } bool GetDirty() { return mDirty; } - void SetProjectTitle(); + void SetProjectTitle( int number =-1); wxPanel *GetTopPanel() { return mTopPanel; } TrackPanel * GetTrackPanel() {return mTrackPanel;} @@ -341,6 +341,9 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame, static TrackList *GetClipboardTracks(); static void DeleteClipboard(); + int GetProjectNumber(); + static int CountUnnamed(); + static void RefreshAllTitles(bool bShowProjectNumbers ); // checkActive is a temporary hack that should be removed as soon as we // get multiple effect preview working void UpdateMenus(bool checkActive = true); From ed7bfd883566d8cc34d2bd338bbfac71e8e57b80 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 1 Sep 2016 18:03:45 -0400 Subject: [PATCH 2/2] Small improvements to the logic of WaveTrackCache --- src/WaveTrack.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index 43831c8fb..17f2fa0da 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -2661,6 +2661,7 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format, mBuffers[1] = mBuffers[0]; mBuffers[0].data = save; fillFirst = true; + fillSecond = false; // Cache is not in a consistent state yet mNValidBuffers = 0; } @@ -2732,7 +2733,7 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format, const auto starti = start - mBuffers[ii].start; const auto leni = std::min( sampleCount( remaining ), mBuffers[ii].len - starti ); - if (initLen == 0 && leni == len) { + if (initLen <= 0 && leni == len) { // All is contiguous already. We can completely avoid copying return samplePtr(mBuffers[ii].data + starti); }