From 5e4250e302f9deb84da9d8df1891a17c8ddff665 Mon Sep 17 00:00:00 2001 From: mchinen Date: Tue, 1 Mar 2011 01:29:03 +0000 Subject: [PATCH] bug 26 - add modeless warning dialog for missing aliased files during playback. --- src/AudioIO.cpp | 30 +++++++++++++++++++++++++++ src/AudioIO.h | 19 +++++++++++++++++ src/Project.cpp | 9 ++++++++ src/blockfile/ODPCMAliasBlockFile.cpp | 5 +++++ src/blockfile/PCMAliasBlockFile.cpp | 7 +++++++ src/widgets/ErrorDialog.cpp | 24 +++++++++++++++++---- src/widgets/ErrorDialog.h | 7 +++++++ 7 files changed, 97 insertions(+), 4 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index a9deaa444..132f83f71 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -477,6 +477,30 @@ void DeinitAudioIO() delete gAudioIO; } +void AudioIO::MarkAliasedFilesMissingWarning() +{ + // only show the warning when we are playing or recording + if (IsStreamActive()) { + m_aliasMissingWarning = true; + } +} + +void AudioIO::SetMissingAliasedFileWarningShouldShow(bool b) +{ + m_aliasMissingWarningShouldShow = b; + // reset the warnings as they were probably marked by a previous run + if (m_aliasMissingWarningShouldShow) { + m_aliasMissingWarning = false; + } +} + +bool AudioIO::ShouldShowMissingAliasedFileWarning() +{ + bool ret = m_aliasMissingWarning && m_aliasMissingWarningShouldShow; + + return ret; +} + wxString DeviceName(const PaDeviceInfo* info) { wxString infoName(info->name, wxConvLocal); @@ -510,6 +534,9 @@ AudioIO::AudioIO() mAudioThreadFillBuffersLoopActive = false; mPortStreamV19 = NULL; + m_aliasMissingWarningShouldShow = false; + m_aliasMissingWarning = false; + #ifdef EXPERIMENTAL_MIDI_OUT mMidiStream = NULL; mMidiThreadFillBuffersLoopRunning = false; @@ -1376,6 +1403,9 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, } #endif + // Enable warning popups for unfound aliased blockfiles. + SetMissingAliasedFileWarningShouldShow(true); + // // Generate an unique value each time, to be returned to // clients accessing the AudioIO API, so they can query if diff --git a/src/AudioIO.h b/src/AudioIO.h index 2d3bf5b78..37ce09b74 100644 --- a/src/AudioIO.h +++ b/src/AudioIO.h @@ -305,6 +305,22 @@ class AUDACITY_DLL_API AudioIO { */ static bool ValidateDeviceNames(wxString play, wxString rec); + /** \brief Mark playback as having missing aliased blockfiles + * + * Playback will continue, but the missing files will be silenced + * ShouldShowMissingAliasedFileWarning can be called to determine + * if the user should be notified + */ + void MarkAliasedFilesMissingWarning(); + + /** \brief Changes the behavior of missing aliased blockfiles warnings + */ + void SetMissingAliasedFileWarningShouldShow(bool b); + + /** \brief Returns true if the user should be notified of missing alias warnings + */ + bool ShouldShowMissingAliasedFileWarning(); + /** \brief Function to automatically set an acceptable volume * */ @@ -509,6 +525,9 @@ private: volatile bool mAudioThreadFillBuffersLoopRunning; volatile bool mAudioThreadFillBuffersLoopActive; + bool m_aliasMissingWarningShouldShow; + bool m_aliasMissingWarning; + #ifdef EXPERIMENTAL_MIDI_OUT volatile bool mMidiThreadFillBuffersLoopRunning; volatile bool mMidiThreadFillBuffersLoopActive; diff --git a/src/Project.cpp b/src/Project.cpp index 76a0fb53e..dadcd8920 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -3898,6 +3898,15 @@ void AudacityProject::OnTimer(wxTimerEvent& event) if( mixerToolBar ) mixerToolBar->UpdateControls(); + // Check if a warning for missing aliased files should be displayed + if (gAudioIO->ShouldShowMissingAliasedFileWarning()) { + wxString errorMessage = _("One or more external audio files could not be found.\nIt is possible they were moved, deleted, or the drive they were on was unmounted.\nSilence is being substituted for the affected audio."); + ShowModelessErrorDialog(this, _("Files Missing"), + errorMessage, wxT("innerlink:wma-proprietary"), true); + // Only show this warning once per playback. + gAudioIO->SetMissingAliasedFileWarningShouldShow(false); + } + if (::wxGetUTCTime() - mLastStatusUpdateTime < 3) return; diff --git a/src/blockfile/ODPCMAliasBlockFile.cpp b/src/blockfile/ODPCMAliasBlockFile.cpp index 2d4fafe7a..f0cee5d3f 100644 --- a/src/blockfile/ODPCMAliasBlockFile.cpp +++ b/src/blockfile/ODPCMAliasBlockFile.cpp @@ -34,9 +34,11 @@ The summary is eventually computed and written to a file in a background thread. #include "../Internat.h" #include "../ondemand/ODManager.h" +#include "../AudioIO.h" //#include +extern AudioIO *gAudioIO; const int aheaderTagLen = 20; char aheaderTag[aheaderTagLen + 1] = "AudacityBlockFile112"; @@ -631,6 +633,9 @@ int ODPCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format, memset(data,0,SAMPLE_SIZE(format)*len); mSilentAliasLog=TRUE; + // Set a marker to display an error message + if (gAudioIO) + gAudioIO->MarkAliasedFilesMissingWarning(); UnlockRead(); return len; diff --git a/src/blockfile/PCMAliasBlockFile.cpp b/src/blockfile/PCMAliasBlockFile.cpp index 31f481188..bf79b7e78 100644 --- a/src/blockfile/PCMAliasBlockFile.cpp +++ b/src/blockfile/PCMAliasBlockFile.cpp @@ -24,6 +24,9 @@ #include "../Internat.h" #include "../ondemand/ODManager.h" +#include "../AudioIO.h" + +extern AudioIO *gAudioIO; PCMAliasBlockFile::PCMAliasBlockFile( wxFileName fileName, @@ -104,6 +107,10 @@ int PCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format, memset(data,0,SAMPLE_SIZE(format)*len); if(silence) delete silence; mSilentAliasLog=TRUE; + + // Set a marker to display an error message for the silence + if (gAudioIO) + gAudioIO->MarkAliasedFilesMissingWarning(); return len; } diff --git a/src/widgets/ErrorDialog.cpp b/src/widgets/ErrorDialog.cpp index ce8981b8d..a079e86ab 100644 --- a/src/widgets/ErrorDialog.cpp +++ b/src/widgets/ErrorDialog.cpp @@ -44,11 +44,12 @@ class ErrorDialog : public wxDialog const wxString & dlogTitle, const wxString & message, const wxString & helpURL, - const bool Close = true); + const bool Close = true, const bool modal = true); private: wxString dhelpURL; bool dClose; + bool dModal; void OnOk( wxCommandEvent &event ); void OnHelp( wxCommandEvent &event ); @@ -66,11 +67,12 @@ ErrorDialog::ErrorDialog( const wxString & dlogTitle, const wxString & message, const wxString & helpURL, - const bool Close): + const bool Close, const bool modal): wxDialog(parent, (wxWindowID)-1, dlogTitle) { dhelpURL = helpURL; dClose = Close; + dModal = modal; ShuttleGui S(this, eIsCreating); @@ -119,8 +121,11 @@ ErrorDialog::ErrorDialog( } void ErrorDialog::OnOk(wxCommandEvent &event) -{ - EndModal(true); +{ + if (dModal) + EndModal(true); + else + Destroy(); } // Helper class to make browser "simulate" a modal dialog @@ -252,6 +257,17 @@ void ShowErrorDialog(wxWindow *parent, dlog.ShowModal(); } +void ShowModelessErrorDialog(wxWindow *parent, + const wxString &dlogTitle, + const wxString &message, + const wxString &helpURL, + const bool Close) +{ + ErrorDialog *dlog = new ErrorDialog(parent, dlogTitle, message, helpURL, Close, false); + dlog->CentreOnParent(); + dlog->Show(); +} + /// Mostly we use this so that we have the code for resizability /// in one place. Other considerations like screen readers are also diff --git a/src/widgets/ErrorDialog.h b/src/widgets/ErrorDialog.h index 371489446..49a39454d 100644 --- a/src/widgets/ErrorDialog.h +++ b/src/widgets/ErrorDialog.h @@ -23,6 +23,13 @@ void ShowErrorDialog(wxWindow *parent, const wxString &helpURL, bool Close = true); +/// Displays a modeless error dialog with a button that offers help +void ShowModelessErrorDialog(wxWindow *parent, + const wxString &dlogTitle, + const wxString &message, + const wxString &helpURL, + bool Close = true); + /// Displays cutable information in a text ctrl, with an OK button. void ShowInfoDialog( wxWindow *parent, const wxString &dlogTitle,