mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-07 16:10:37 +02:00
bug 26 followup - warn of missing alias on variety of instances (export/import/effect/mix,) in addition to first time the read fails.\nIn addition make sure there is only one warning on the screen at a time, bringing the old one to the foreground (although for things like export/effect there will be a progress bar in front of it, the missing files dialog will be above the project window when it finishes)
This commit is contained in:
parent
686f3796ae
commit
dc12d8a8f4
@ -479,14 +479,15 @@ void DeinitAudioIO()
|
|||||||
|
|
||||||
void AudioIO::MarkAliasedFilesMissingWarning()
|
void AudioIO::MarkAliasedFilesMissingWarning()
|
||||||
{
|
{
|
||||||
// only show the warning when we are playing or recording
|
m_aliasMissingWarning = true;
|
||||||
if (IsStreamActive()) {
|
|
||||||
m_aliasMissingWarning = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioIO::SetMissingAliasedFileWarningShouldShow(bool b)
|
void AudioIO::SetMissingAliasedFileWarningShouldShow(bool b)
|
||||||
{
|
{
|
||||||
|
// Note that this is can be called by both the main thread and other threads.
|
||||||
|
// I don't believe we need a mutex because we are checking zero vs non-zero,
|
||||||
|
// and the setting from other threads will always be non-zero (true), and the
|
||||||
|
// setting from the main thread is always false.
|
||||||
m_aliasMissingWarningShouldShow = b;
|
m_aliasMissingWarningShouldShow = b;
|
||||||
// reset the warnings as they were probably marked by a previous run
|
// reset the warnings as they were probably marked by a previous run
|
||||||
if (m_aliasMissingWarningShouldShow) {
|
if (m_aliasMissingWarningShouldShow) {
|
||||||
@ -501,6 +502,17 @@ bool AudioIO::ShouldShowMissingAliasedFileWarning()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioIO::SetMissingAliasFileDialog(wxDialog *dialog)
|
||||||
|
{
|
||||||
|
m_aliasMissingWarningDialog = dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDialog *AudioIO::GetMissingAliasFileDialog()
|
||||||
|
{
|
||||||
|
return m_aliasMissingWarningDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString DeviceName(const PaDeviceInfo* info)
|
wxString DeviceName(const PaDeviceInfo* info)
|
||||||
{
|
{
|
||||||
wxString infoName(info->name, wxConvLocal);
|
wxString infoName(info->name, wxConvLocal);
|
||||||
@ -534,8 +546,9 @@ AudioIO::AudioIO()
|
|||||||
mAudioThreadFillBuffersLoopActive = false;
|
mAudioThreadFillBuffersLoopActive = false;
|
||||||
mPortStreamV19 = NULL;
|
mPortStreamV19 = NULL;
|
||||||
|
|
||||||
m_aliasMissingWarningShouldShow = false;
|
m_aliasMissingWarningShouldShow = true;
|
||||||
m_aliasMissingWarning = false;
|
m_aliasMissingWarning = false;
|
||||||
|
m_aliasMissingWarningDialog = NULL;
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
mMidiStream = NULL;
|
mMidiStream = NULL;
|
||||||
|
@ -43,6 +43,7 @@ class TimeTrack;
|
|||||||
class AudioThread;
|
class AudioThread;
|
||||||
class Meter;
|
class Meter;
|
||||||
class TimeTrack;
|
class TimeTrack;
|
||||||
|
class wxDialog;
|
||||||
|
|
||||||
extern AUDACITY_DLL_API AudioIO *gAudioIO;
|
extern AUDACITY_DLL_API AudioIO *gAudioIO;
|
||||||
|
|
||||||
@ -320,6 +321,15 @@ class AUDACITY_DLL_API AudioIO {
|
|||||||
/** \brief Returns true if the user should be notified of missing alias warnings
|
/** \brief Returns true if the user should be notified of missing alias warnings
|
||||||
*/
|
*/
|
||||||
bool ShouldShowMissingAliasedFileWarning();
|
bool ShouldShowMissingAliasedFileWarning();
|
||||||
|
|
||||||
|
/** \brief Sets the wxDialog that is being displayed
|
||||||
|
* Used by the custom dialog warning constructor and destructor
|
||||||
|
*/
|
||||||
|
void SetMissingAliasFileDialog(wxDialog *dialog);
|
||||||
|
|
||||||
|
/** \brief returns a pointer to the wxDialog if it is displayed, NULL otherwise.
|
||||||
|
*/
|
||||||
|
wxDialog *GetMissingAliasFileDialog();
|
||||||
|
|
||||||
/** \brief Function to automatically set an acceptable volume
|
/** \brief Function to automatically set an acceptable volume
|
||||||
*
|
*
|
||||||
@ -527,6 +537,7 @@ private:
|
|||||||
|
|
||||||
bool m_aliasMissingWarningShouldShow;
|
bool m_aliasMissingWarningShouldShow;
|
||||||
bool m_aliasMissingWarning;
|
bool m_aliasMissingWarning;
|
||||||
|
wxDialog *m_aliasMissingWarningDialog;
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
volatile bool mMidiThreadFillBuffersLoopRunning;
|
volatile bool mMidiThreadFillBuffersLoopRunning;
|
||||||
|
@ -2665,6 +2665,9 @@ bool AudacityProject::OnEffect(int type,
|
|||||||
wxString params,
|
wxString params,
|
||||||
bool saveState)
|
bool saveState)
|
||||||
{
|
{
|
||||||
|
if (gAudioIO)
|
||||||
|
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||||
|
|
||||||
TrackListIterator iter(mTracks);
|
TrackListIterator iter(mTracks);
|
||||||
Track *t = iter.First();
|
Track *t = iter.First();
|
||||||
WaveTrack *newTrack = NULL;
|
WaveTrack *newTrack = NULL;
|
||||||
@ -3024,6 +3027,8 @@ void AudacityProject::OnExport()
|
|||||||
{
|
{
|
||||||
Exporter e;
|
Exporter e;
|
||||||
|
|
||||||
|
if (gAudioIO)
|
||||||
|
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||||
e.Process(this, false, 0.0, mTracks->GetEndTime());
|
e.Process(this, false, 0.0, mTracks->GetEndTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3031,6 +3036,8 @@ void AudacityProject::OnExportSelection()
|
|||||||
{
|
{
|
||||||
Exporter e;
|
Exporter e;
|
||||||
|
|
||||||
|
if (gAudioIO)
|
||||||
|
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||||
e.Process(this, true, mViewInfo.sel0, mViewInfo.sel1);
|
e.Process(this, true, mViewInfo.sel0, mViewInfo.sel1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3038,6 +3045,8 @@ void AudacityProject::OnExportMultiple()
|
|||||||
{
|
{
|
||||||
ExportMultiple em(this);
|
ExportMultiple em(this);
|
||||||
|
|
||||||
|
if (gAudioIO)
|
||||||
|
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||||
em.ShowModal();
|
em.ShowModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4603,6 +4612,11 @@ void AudacityProject::OnSimplifiedView()
|
|||||||
|
|
||||||
void AudacityProject::OnImport()
|
void AudacityProject::OnImport()
|
||||||
{
|
{
|
||||||
|
// An import trigger for the alias missing dialog might not be intuitive, but
|
||||||
|
// this serves to track the file if the users zooms in and such.
|
||||||
|
if (gAudioIO)
|
||||||
|
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||||
|
|
||||||
wxArrayString selectedFiles = ShowOpenDialog(wxT(""));
|
wxArrayString selectedFiles = ShowOpenDialog(wxT(""));
|
||||||
if (selectedFiles.GetCount() == 0) {
|
if (selectedFiles.GetCount() == 0) {
|
||||||
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
|
gPrefs->Write(wxT("/LastOpenType"),wxT(""));
|
||||||
@ -4748,6 +4762,9 @@ void AudacityProject::HandleMixAndRender(bool toNewTrack)
|
|||||||
WaveTrack *newLeft = NULL;
|
WaveTrack *newLeft = NULL;
|
||||||
WaveTrack *newRight = NULL;
|
WaveTrack *newRight = NULL;
|
||||||
|
|
||||||
|
if (gAudioIO)
|
||||||
|
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||||
|
|
||||||
if (::MixAndRender(mTracks, mTrackFactory, mRate, mDefaultFormat, 0.0, 0.0,
|
if (::MixAndRender(mTracks, mTrackFactory, mRate, mDefaultFormat, 0.0, 0.0,
|
||||||
&newLeft, &newRight)) {
|
&newLeft, &newRight)) {
|
||||||
|
|
||||||
|
@ -760,6 +760,9 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
|||||||
mStatusBar = CreateStatusBar(2);
|
mStatusBar = CreateStatusBar(2);
|
||||||
mStatusBar->SetStatusWidths(2, widths);
|
mStatusBar->SetStatusWidths(2, widths);
|
||||||
|
|
||||||
|
if (gAudioIO)
|
||||||
|
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||||
|
|
||||||
// MM: DirManager is created dynamically, freed on demand via ref-counting
|
// MM: DirManager is created dynamically, freed on demand via ref-counting
|
||||||
// MM: We don't need to Ref() here because it start with refcount=1
|
// MM: We don't need to Ref() here because it start with refcount=1
|
||||||
mDirManager = new DirManager();
|
mDirManager = new DirManager();
|
||||||
@ -3905,16 +3908,22 @@ void AudacityProject::OnTimer(wxTimerEvent& event)
|
|||||||
|
|
||||||
// Check if a warning for missing aliased files should be displayed
|
// Check if a warning for missing aliased files should be displayed
|
||||||
if (gAudioIO->ShouldShowMissingAliasedFileWarning()) {
|
if (gAudioIO->ShouldShowMissingAliasedFileWarning()) {
|
||||||
wxString errorMessage = _(
|
if (gAudioIO->GetMissingAliasFileDialog()) {
|
||||||
|
// if it is already shown, just bring it to the front instead of
|
||||||
|
// creating a new one.
|
||||||
|
gAudioIO->GetMissingAliasFileDialog()->Raise();
|
||||||
|
} else {
|
||||||
|
wxString errorMessage = _(
|
||||||
"One or more external audio files could not be found.\n\
|
"One or more external audio files could not be found.\n\
|
||||||
It is possible they were moved, deleted, or the drive they \
|
It is possible they were moved, deleted, or the drive they \
|
||||||
were on was unmounted.\n\
|
were on was unmounted.\n\
|
||||||
Silence is being substituted for the affected audio.\n\
|
Silence is being substituted for the affected audio.\n\
|
||||||
Choose File > Check Dependencies to view the \
|
Choose File > Check Dependencies to view the \
|
||||||
original location of the missing files.");
|
original location of the missing files.");
|
||||||
ShowModelessErrorDialog(this, _("Files Missing"),
|
ShowAliasMissingDialog(this, _("Files Missing"),
|
||||||
errorMessage, wxT(""), true);
|
errorMessage, wxT(""), true);
|
||||||
// Only show this warning once per playback.
|
// Only show this warning once per playback.
|
||||||
|
}
|
||||||
gAudioIO->SetMissingAliasedFileWarningShouldShow(false);
|
gAudioIO->SetMissingAliasedFileWarningShouldShow(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ Gives an Error message with an option for help.
|
|||||||
#include "../Internat.h"
|
#include "../Internat.h"
|
||||||
#include "../Project.h"
|
#include "../Project.h"
|
||||||
#include "../Prefs.h"
|
#include "../Prefs.h"
|
||||||
|
#include "../AudioIO.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ErrorDialog : public wxDialog
|
class ErrorDialog : public wxDialog
|
||||||
{
|
{
|
||||||
@ -46,6 +49,8 @@ class ErrorDialog : public wxDialog
|
|||||||
const wxString & helpURL,
|
const wxString & helpURL,
|
||||||
const bool Close = true, const bool modal = true);
|
const bool Close = true, const bool modal = true);
|
||||||
|
|
||||||
|
virtual ~ErrorDialog(){}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxString dhelpURL;
|
wxString dhelpURL;
|
||||||
bool dClose;
|
bool dClose;
|
||||||
@ -57,11 +62,39 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// special case for alias missing dialog because we keep track of if it exists.
|
||||||
|
class AliasedFileMissingDialog : public ErrorDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AliasedFileMissingDialog(wxWindow *parent,
|
||||||
|
const wxString & dlogTitle,
|
||||||
|
const wxString & message,
|
||||||
|
const wxString & helpURL,
|
||||||
|
const bool Close = true, const bool modal = true);
|
||||||
|
virtual ~AliasedFileMissingDialog();
|
||||||
|
};
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(ErrorDialog, wxDialog)
|
BEGIN_EVENT_TABLE(ErrorDialog, wxDialog)
|
||||||
EVT_BUTTON( wxID_OK, ErrorDialog::OnOk)
|
EVT_BUTTON( wxID_OK, ErrorDialog::OnOk)
|
||||||
EVT_BUTTON( wxID_HELP, ErrorDialog::OnHelp)
|
EVT_BUTTON( wxID_HELP, ErrorDialog::OnHelp)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
AliasedFileMissingDialog::AliasedFileMissingDialog(wxWindow *parent,
|
||||||
|
const wxString & dlogTitle,
|
||||||
|
const wxString & message,
|
||||||
|
const wxString & helpURL,
|
||||||
|
const bool Close, const bool modal):
|
||||||
|
ErrorDialog(parent, dlogTitle, message, helpURL, Close, modal)
|
||||||
|
{
|
||||||
|
gAudioIO->SetMissingAliasFileDialog(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
AliasedFileMissingDialog::~AliasedFileMissingDialog()
|
||||||
|
{
|
||||||
|
gAudioIO->SetMissingAliasFileDialog(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
ErrorDialog::ErrorDialog(
|
ErrorDialog::ErrorDialog(
|
||||||
wxWindow *parent,
|
wxWindow *parent,
|
||||||
const wxString & dlogTitle,
|
const wxString & dlogTitle,
|
||||||
@ -272,6 +305,27 @@ void ShowModelessErrorDialog(wxWindow *parent,
|
|||||||
dlog->Show();
|
dlog->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShowAliasMissingDialog(wxWindow *parent,
|
||||||
|
const wxString &dlogTitle,
|
||||||
|
const wxString &message,
|
||||||
|
const wxString &helpURL,
|
||||||
|
const bool Close)
|
||||||
|
{
|
||||||
|
ErrorDialog *dlog = new AliasedFileMissingDialog(parent, dlogTitle, message, helpURL, Close, false);
|
||||||
|
// Don't center because in many cases (effect, export, etc) there will be a progress bar in the center that blocks this.
|
||||||
|
// instead put it just above or on the top of the project.
|
||||||
|
wxPoint point;
|
||||||
|
point.x = 0;
|
||||||
|
|
||||||
|
point.y = parent ? parent->GetPosition().y - 200 : 100;
|
||||||
|
|
||||||
|
if (point.y < 100)
|
||||||
|
point.y = 100;
|
||||||
|
dlog->SetPosition(point);
|
||||||
|
dlog->CentreOnParent(wxHORIZONTAL);
|
||||||
|
|
||||||
|
dlog->Show();
|
||||||
|
}
|
||||||
|
|
||||||
/// Mostly we use this so that we have the code for resizability
|
/// Mostly we use this so that we have the code for resizability
|
||||||
/// in one place. Other considerations like screen readers are also
|
/// in one place. Other considerations like screen readers are also
|
||||||
|
@ -30,6 +30,13 @@ void ShowModelessErrorDialog(wxWindow *parent,
|
|||||||
const wxString &helpURL,
|
const wxString &helpURL,
|
||||||
bool Close = true);
|
bool Close = true);
|
||||||
|
|
||||||
|
/// Displays a custom modeless error dialog for aliased file errors
|
||||||
|
void ShowAliasMissingDialog(wxWindow *parent,
|
||||||
|
const wxString &dlogTitle,
|
||||||
|
const wxString &message,
|
||||||
|
const wxString &helpURL,
|
||||||
|
const bool Close = true);
|
||||||
|
|
||||||
/// Displays cutable information in a text ctrl, with an OK button.
|
/// Displays cutable information in a text ctrl, with an OK button.
|
||||||
void ShowInfoDialog( wxWindow *parent,
|
void ShowInfoDialog( wxWindow *parent,
|
||||||
const wxString &dlogTitle,
|
const wxString &dlogTitle,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user