mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-02 00:29:41 +02:00
Bug 330 (P2) - Fix an issue where multiple projects would cause the warning dialogs to pop up above the wrong project.
I refactored the code into AudacityApp with a new timer. This is provisional pending discussion - if it is decided that it should go somewhere else I will move it.
This commit is contained in:
parent
c226ae9265
commit
91d8f132a6
@ -88,6 +88,8 @@ It handles initialization and termination by subclassing wxApp.
|
||||
#include "BlockFile.h"
|
||||
#include "ondemand/ODManager.h"
|
||||
#include "commands/Keyboard.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
|
||||
//temporarilly commented out till it is added to all projects
|
||||
//#include "Profiler.h"
|
||||
|
||||
@ -712,12 +714,16 @@ typedef int (AudacityApp::*SPECIALKEYEVENT)(wxKeyEvent&);
|
||||
#define ID_RECENT_FIRST 6101
|
||||
#define ID_RECENT_LAST 6112
|
||||
|
||||
// we don't really care about the timer id, but set this value just in case we do in the future
|
||||
#define kAudacityAppTimerID 0
|
||||
|
||||
BEGIN_EVENT_TABLE(AudacityApp, wxApp)
|
||||
EVT_QUERY_END_SESSION(AudacityApp::OnEndSession)
|
||||
|
||||
EVT_KEY_DOWN(AudacityApp::OnKeyDown)
|
||||
EVT_CHAR(AudacityApp::OnChar)
|
||||
EVT_KEY_UP(AudacityApp::OnKeyUp)
|
||||
EVT_TIMER(kAudacityAppTimerID, AudacityApp::OnTimer)
|
||||
#ifdef __WXMAC__
|
||||
EVT_MENU(wxID_NEW, AudacityApp::OnMenuNew)
|
||||
EVT_MENU(wxID_OPEN, AudacityApp::OnMenuOpen)
|
||||
@ -805,6 +811,99 @@ void AudacityApp::OnMRUFile(wxCommandEvent& event) {
|
||||
mRecentFiles->RemoveFileFromHistory(n);
|
||||
}
|
||||
|
||||
void AudacityApp::OnTimer(wxTimerEvent& event)
|
||||
{
|
||||
// Check if a warning for missing aliased files should be displayed
|
||||
if (ShouldShowMissingAliasedFileWarning()) {
|
||||
if (GetMissingAliasFileDialog()) {
|
||||
// if it is already shown, just bring it to the front instead of
|
||||
// creating a new one.
|
||||
GetMissingAliasFileDialog()->Raise();
|
||||
} else {
|
||||
wxString errorMessage = _(
|
||||
"One or more external audio files could not be found.\n\
|
||||
It is possible they were moved, deleted, or the drive they \
|
||||
were on was unmounted.\n\
|
||||
Silence is being substituted for the affected audio.\n\
|
||||
Choose File > Check Dependencies to view the \
|
||||
original location of the missing files.");
|
||||
|
||||
// find which project owns the blockfile
|
||||
// note: there may be more than 1, but just go with the first one.
|
||||
size_t numProjects = gAudacityProjects.Count();
|
||||
AudacityProject *offendingProject = NULL;
|
||||
if (numProjects == 1) {
|
||||
// if there is only one project open, no need to search
|
||||
offendingProject = gAudacityProjects[0];
|
||||
} else if (numProjects > 1) {
|
||||
|
||||
m_LastMissingBlockFileLock.Lock();
|
||||
for (size_t i = 0; i < numProjects; i++)
|
||||
{
|
||||
// search each project for the blockfile
|
||||
if (gAudacityProjects[i]->GetDirManager()->ContainsBlockFile(m_LastMissingBlockFile)) {
|
||||
offendingProject = gAudacityProjects[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_LastMissingBlockFileLock.Unlock();
|
||||
}
|
||||
|
||||
// if there are no projects open, don't show the warning (user has closed it)
|
||||
if (offendingProject)
|
||||
ShowAliasMissingDialog(offendingProject, _("Files Missing"),
|
||||
errorMessage, wxT(""), true);
|
||||
// Only show this warning once per playback.
|
||||
}
|
||||
SetMissingAliasedFileWarningShouldShow(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AudacityApp::MarkAliasedFilesMissingWarning(BlockFile *b)
|
||||
{
|
||||
// the reference counting provides thread safety.
|
||||
if (b)
|
||||
b->Ref();
|
||||
|
||||
m_LastMissingBlockFileLock.Lock();
|
||||
if (m_LastMissingBlockFile)
|
||||
m_LastMissingBlockFile->Deref();
|
||||
|
||||
m_LastMissingBlockFile = b;
|
||||
|
||||
m_LastMissingBlockFileLock.Unlock();
|
||||
}
|
||||
|
||||
void AudacityApp::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;
|
||||
// reset the warnings as they were probably marked by a previous run
|
||||
if (m_aliasMissingWarningShouldShow) {
|
||||
MarkAliasedFilesMissingWarning(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool AudacityApp::ShouldShowMissingAliasedFileWarning()
|
||||
{
|
||||
bool ret = m_LastMissingBlockFile && m_aliasMissingWarningShouldShow;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudacityApp::SetMissingAliasFileDialog(wxDialog *dialog)
|
||||
{
|
||||
m_aliasMissingWarningDialog = dialog;
|
||||
}
|
||||
|
||||
wxDialog *AudacityApp::GetMissingAliasFileDialog()
|
||||
{
|
||||
return m_aliasMissingWarningDialog;
|
||||
}
|
||||
|
||||
void AudacityApp::InitLang( const wxString & lang )
|
||||
{
|
||||
if( mLocale )
|
||||
@ -862,6 +961,10 @@ void AudacityApp::OnFatalException()
|
||||
// main frame
|
||||
bool AudacityApp::OnInit()
|
||||
{
|
||||
m_aliasMissingWarningShouldShow = true;
|
||||
m_LastMissingBlockFile = NULL;
|
||||
m_aliasMissingWarningDialog = NULL;
|
||||
|
||||
#if defined(__WXGTK__)
|
||||
// Workaround for bug 154 -- initialize to false
|
||||
inKbdHandler = false;
|
||||
@ -1296,6 +1399,8 @@ bool AudacityApp::OnInit()
|
||||
|
||||
wxLog::FlushActive(); // Make sure all log messages are written.
|
||||
|
||||
mTimer = new wxTimer(this, kAudacityAppTimerID);
|
||||
mTimer->Start(200);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <wx/log.h>
|
||||
|
||||
#include "widgets/FileHistory.h"
|
||||
#include "ondemand/ODTaskThread.h"
|
||||
|
||||
class IPCServ;
|
||||
class Importer;
|
||||
@ -87,6 +88,8 @@ enum
|
||||
NoFlagsSpecifed = 0xffffffff
|
||||
};
|
||||
|
||||
class BlockFile;
|
||||
|
||||
class AudacityApp:public wxApp {
|
||||
public:
|
||||
virtual bool OnInit(void);
|
||||
@ -127,6 +130,33 @@ class AudacityApp:public wxApp {
|
||||
|
||||
void OnReceiveCommand(AppCommandEvent &event);
|
||||
|
||||
void OnTimer(wxTimerEvent & event);
|
||||
|
||||
/** \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(BlockFile *b);
|
||||
|
||||
/** \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 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();
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// In response to Apple Events
|
||||
virtual void MacOpenFile(const wxString &fileName) ;
|
||||
@ -186,6 +216,14 @@ class AudacityApp:public wxApp {
|
||||
|
||||
wxSingleInstanceChecker *mChecker;
|
||||
|
||||
wxTimer *mTimer;
|
||||
|
||||
bool m_aliasMissingWarningShouldShow;
|
||||
wxDialog *m_aliasMissingWarningDialog;
|
||||
BlockFile *m_LastMissingBlockFile;
|
||||
|
||||
ODLock m_LastMissingBlockFileLock;
|
||||
|
||||
void InitCommandHandler();
|
||||
void DeInitCommandHandler();
|
||||
|
||||
|
@ -477,42 +477,6 @@ void DeinitAudioIO()
|
||||
delete gAudioIO;
|
||||
}
|
||||
|
||||
void AudioIO::MarkAliasedFilesMissingWarning()
|
||||
{
|
||||
m_aliasMissingWarning = true;
|
||||
}
|
||||
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
|
||||
void AudioIO::SetMissingAliasFileDialog(wxDialog *dialog)
|
||||
{
|
||||
m_aliasMissingWarningDialog = dialog;
|
||||
}
|
||||
|
||||
wxDialog *AudioIO::GetMissingAliasFileDialog()
|
||||
{
|
||||
return m_aliasMissingWarningDialog;
|
||||
}
|
||||
|
||||
|
||||
wxString DeviceName(const PaDeviceInfo* info)
|
||||
{
|
||||
wxString infoName(info->name, wxConvLocal);
|
||||
@ -546,10 +510,6 @@ AudioIO::AudioIO()
|
||||
mAudioThreadFillBuffersLoopActive = false;
|
||||
mPortStreamV19 = NULL;
|
||||
|
||||
m_aliasMissingWarningShouldShow = true;
|
||||
m_aliasMissingWarning = false;
|
||||
m_aliasMissingWarningDialog = NULL;
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
mMidiStream = NULL;
|
||||
mMidiThreadFillBuffersLoopRunning = false;
|
||||
@ -1417,7 +1377,7 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks,
|
||||
#endif
|
||||
|
||||
// Enable warning popups for unfound aliased blockfiles.
|
||||
SetMissingAliasedFileWarningShouldShow(true);
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
|
||||
//
|
||||
// Generate an unique value each time, to be returned to
|
||||
|
@ -306,31 +306,6 @@ 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 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
|
||||
*
|
||||
*/
|
||||
@ -535,10 +510,6 @@ private:
|
||||
volatile bool mAudioThreadFillBuffersLoopRunning;
|
||||
volatile bool mAudioThreadFillBuffersLoopActive;
|
||||
|
||||
bool m_aliasMissingWarningShouldShow;
|
||||
bool m_aliasMissingWarning;
|
||||
wxDialog *m_aliasMissingWarningDialog;
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
volatile bool mMidiThreadFillBuffersLoopRunning;
|
||||
volatile bool mMidiThreadFillBuffersLoopActive;
|
||||
|
@ -133,6 +133,7 @@ class BlockFile {
|
||||
private:
|
||||
|
||||
friend class DirManager;
|
||||
friend class AudacityApp;
|
||||
//needed for Ref/Deref access.
|
||||
friend class ODComputeSummaryTask;
|
||||
friend class ODDecodeTask;
|
||||
|
@ -910,6 +910,11 @@ BlockFile *DirManager::NewODDecodeBlockFile(
|
||||
return newBlockFile;
|
||||
}
|
||||
|
||||
bool DirManager::ContainsBlockFile(BlockFile *b) {
|
||||
// check what the hash returns in case the blockfile is from a different project
|
||||
return b ? mBlockFileHash[b->GetFileName().GetName()] == b : NULL;
|
||||
}
|
||||
|
||||
// Adds one to the reference count of the block file,
|
||||
// UNLESS it is "locked", then it makes a new copy of
|
||||
// the BlockFile.
|
||||
|
@ -70,6 +70,9 @@ class DirManager: public XMLTagHandler {
|
||||
BlockFile *NewODDecodeBlockFile( wxString aliasedFile, sampleCount aliasStart,
|
||||
sampleCount aliasLen, int aliasChannel, int decodeType);
|
||||
|
||||
/// Returns true if the blockfile is contained by the DirManager
|
||||
bool ContainsBlockFile(BlockFile *b);
|
||||
|
||||
// Adds one to the reference count of the block file,
|
||||
// UNLESS it is "locked", then it makes a new copy of
|
||||
// the BlockFile.
|
||||
|
@ -2665,8 +2665,7 @@ bool AudacityProject::OnEffect(int type,
|
||||
wxString params,
|
||||
bool saveState)
|
||||
{
|
||||
if (gAudioIO)
|
||||
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
|
||||
TrackListIterator iter(mTracks);
|
||||
Track *t = iter.First();
|
||||
@ -3027,8 +3026,7 @@ void AudacityProject::OnExport()
|
||||
{
|
||||
Exporter e;
|
||||
|
||||
if (gAudioIO)
|
||||
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
e.Process(this, false, 0.0, mTracks->GetEndTime());
|
||||
}
|
||||
|
||||
@ -3036,8 +3034,7 @@ void AudacityProject::OnExportSelection()
|
||||
{
|
||||
Exporter e;
|
||||
|
||||
if (gAudioIO)
|
||||
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
e.Process(this, true, mViewInfo.sel0, mViewInfo.sel1);
|
||||
}
|
||||
|
||||
@ -3045,8 +3042,7 @@ void AudacityProject::OnExportMultiple()
|
||||
{
|
||||
ExportMultiple em(this);
|
||||
|
||||
if (gAudioIO)
|
||||
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
em.ShowModal();
|
||||
}
|
||||
|
||||
@ -4614,8 +4610,7 @@ 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);
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
|
||||
wxArrayString selectedFiles = ShowOpenDialog(wxT(""));
|
||||
if (selectedFiles.GetCount() == 0) {
|
||||
@ -4762,8 +4757,7 @@ void AudacityProject::HandleMixAndRender(bool toNewTrack)
|
||||
WaveTrack *newLeft = NULL;
|
||||
WaveTrack *newRight = NULL;
|
||||
|
||||
if (gAudioIO)
|
||||
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
|
||||
if (::MixAndRender(mTracks, mTrackFactory, mRate, mDefaultFormat, 0.0, 0.0,
|
||||
&newLeft, &newRight)) {
|
||||
|
@ -760,8 +760,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
mStatusBar = CreateStatusBar(2);
|
||||
mStatusBar->SetStatusWidths(2, widths);
|
||||
|
||||
if (gAudioIO)
|
||||
gAudioIO->SetMissingAliasedFileWarningShouldShow(true);
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
|
||||
// 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
|
||||
@ -3931,27 +3930,6 @@ void AudacityProject::OnTimer(wxTimerEvent& event)
|
||||
if( mixerToolBar )
|
||||
mixerToolBar->UpdateControls();
|
||||
|
||||
// Check if a warning for missing aliased files should be displayed
|
||||
if (gAudioIO->ShouldShowMissingAliasedFileWarning()) {
|
||||
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\
|
||||
It is possible they were moved, deleted, or the drive they \
|
||||
were on was unmounted.\n\
|
||||
Silence is being substituted for the affected audio.\n\
|
||||
Choose File > Check Dependencies to view the \
|
||||
original location of the missing files.");
|
||||
ShowAliasMissingDialog(this, _("Files Missing"),
|
||||
errorMessage, wxT(""), true);
|
||||
// Only show this warning once per playback.
|
||||
}
|
||||
gAudioIO->SetMissingAliasedFileWarningShouldShow(false);
|
||||
}
|
||||
|
||||
if (::wxGetUTCTime() - mLastStatusUpdateTime < 3)
|
||||
return;
|
||||
|
||||
|
@ -634,8 +634,8 @@ int ODPCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||
|
||||
mSilentAliasLog=TRUE;
|
||||
// Set a marker to display an error message
|
||||
if (gAudioIO)
|
||||
gAudioIO->MarkAliasedFilesMissingWarning();
|
||||
if (!wxGetApp().ShouldShowMissingAliasedFileWarning())
|
||||
wxGetApp().MarkAliasedFilesMissingWarning(this);
|
||||
|
||||
UnlockRead();
|
||||
return len;
|
||||
|
@ -109,8 +109,8 @@ int PCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||
mSilentAliasLog=TRUE;
|
||||
|
||||
// Set a marker to display an error message for the silence
|
||||
if (gAudioIO)
|
||||
gAudioIO->MarkAliasedFilesMissingWarning();
|
||||
if (!wxGetApp().ShouldShowMissingAliasedFileWarning())
|
||||
wxGetApp().MarkAliasedFilesMissingWarning(this);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,7 @@ Gives an Error message with an option for help.
|
||||
#include "../Internat.h"
|
||||
#include "../Project.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../AudioIO.h"
|
||||
|
||||
#include "../AudacityApp.h"
|
||||
|
||||
|
||||
class ErrorDialog : public wxDialog
|
||||
@ -87,12 +86,12 @@ AliasedFileMissingDialog::AliasedFileMissingDialog(wxWindow *parent,
|
||||
const bool Close, const bool modal):
|
||||
ErrorDialog(parent, dlogTitle, message, helpURL, Close, modal)
|
||||
{
|
||||
gAudioIO->SetMissingAliasFileDialog(this);
|
||||
wxGetApp().SetMissingAliasFileDialog(this);
|
||||
}
|
||||
|
||||
AliasedFileMissingDialog::~AliasedFileMissingDialog()
|
||||
{
|
||||
gAudioIO->SetMissingAliasFileDialog(NULL);
|
||||
wxGetApp().SetMissingAliasFileDialog(NULL);
|
||||
}
|
||||
|
||||
ErrorDialog::ErrorDialog(
|
||||
|
Loading…
x
Reference in New Issue
Block a user