mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-16 16:20:50 +02:00
Detect failure to reconnect to temp project when first saving it
This commit is contained in:
parent
41eb66fccf
commit
aa0b33dc8f
@ -44,6 +44,7 @@ Paul Licameli split from AudacityProject.cpp
|
|||||||
|
|
||||||
wxDEFINE_EVENT(EVT_PROJECT_TITLE_CHANGE, wxCommandEvent);
|
wxDEFINE_EVENT(EVT_PROJECT_TITLE_CHANGE, wxCommandEvent);
|
||||||
wxDEFINE_EVENT( EVT_CHECKPOINT_FAILURE, wxCommandEvent);
|
wxDEFINE_EVENT( EVT_CHECKPOINT_FAILURE, wxCommandEvent);
|
||||||
|
wxDEFINE_EVENT( EVT_RECONNECTION_FAILURE, wxCommandEvent);
|
||||||
|
|
||||||
static const int ProjectFileID = ('A' << 24 | 'U' << 16 | 'D' << 8 | 'Y');
|
static const int ProjectFileID = ('A' << 24 | 'U' << 16 | 'D' << 8 | 'Y');
|
||||||
static const int ProjectFileVersion = 1;
|
static const int ProjectFileVersion = 1;
|
||||||
@ -263,6 +264,12 @@ ProjectFileIO::~ProjectFileIO()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProjectFileIO::HasConnection() const
|
||||||
|
{
|
||||||
|
auto &connectionPtr = ConnectionPtr::Get( mProject );
|
||||||
|
return connectionPtr.mpConnection != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
DBConnection &ProjectFileIO::GetConnection()
|
DBConnection &ProjectFileIO::GetConnection()
|
||||||
{
|
{
|
||||||
auto &curConn = CurrConn();
|
auto &curConn = CurrConn();
|
||||||
@ -2045,20 +2052,38 @@ bool ProjectFileIO::SaveProject(
|
|||||||
FilePath savedName = mFileName;
|
FilePath savedName = mFileName;
|
||||||
if (CloseConnection())
|
if (CloseConnection())
|
||||||
{
|
{
|
||||||
if (MoveProject(savedName, fileName))
|
bool reopened = false;
|
||||||
|
bool moved = false;
|
||||||
|
if (true == (moved = MoveProject(savedName, fileName)))
|
||||||
{
|
{
|
||||||
if (!OpenConnection(fileName))
|
if (OpenConnection(fileName))
|
||||||
{
|
reopened = true;
|
||||||
|
else {
|
||||||
MoveProject(fileName, savedName);
|
MoveProject(fileName, savedName);
|
||||||
OpenConnection(savedName);
|
reopened = OpenConnection(savedName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Rename can fail -- if it's to a different device, requiring
|
// Rename can fail -- if it's to a different device, requiring
|
||||||
// real copy of contents, which might exhaust space
|
// real copy of contents, which might exhaust space
|
||||||
OpenConnection(savedName);
|
reopened = OpenConnection(savedName);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!reopened)
|
||||||
|
wxTheApp->CallAfter([this]{
|
||||||
|
ShowErrorDialog(nullptr,
|
||||||
|
XO("Warning"),
|
||||||
|
XO(
|
||||||
|
"The project's database failed to reopen, "
|
||||||
|
"possibly because of limited space on the storage device."),
|
||||||
|
"Error:_Disk_full_or_not_writable"
|
||||||
|
);
|
||||||
|
wxCommandEvent evt{ EVT_RECONNECTION_FAILURE };
|
||||||
|
mProject.ProcessEvent(evt);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!moved)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,11 @@ using BlockIDs = std::unordered_set<SampleBlockID>;
|
|||||||
wxDECLARE_EXPORTED_EVENT( AUDACITY_DLL_API,
|
wxDECLARE_EXPORTED_EVENT( AUDACITY_DLL_API,
|
||||||
EVT_CHECKPOINT_FAILURE, wxCommandEvent );
|
EVT_CHECKPOINT_FAILURE, wxCommandEvent );
|
||||||
|
|
||||||
|
// An event processed by the project in the main thread after failure to
|
||||||
|
// reconnect to the database, after temporary close and attempted file movement
|
||||||
|
wxDECLARE_EXPORTED_EVENT( AUDACITY_DLL_API,
|
||||||
|
EVT_RECONNECTION_FAILURE, wxCommandEvent );
|
||||||
|
|
||||||
///\brief Object associated with a project that manages reading and writing
|
///\brief Object associated with a project that manages reading and writing
|
||||||
/// of Audacity project file formats, and autosave
|
/// of Audacity project file formats, and autosave
|
||||||
class ProjectFileIO final
|
class ProjectFileIO final
|
||||||
@ -179,6 +184,10 @@ public:
|
|||||||
// 0 for success or non-zero to stop the query
|
// 0 for success or non-zero to stop the query
|
||||||
using ExecCB = std::function<int(int cols, char **vals, char **names)>;
|
using ExecCB = std::function<int(int cols, char **vals, char **names)>;
|
||||||
|
|
||||||
|
//! Return true if a connetion is now open
|
||||||
|
bool HasConnection() const;
|
||||||
|
|
||||||
|
//! Return a reference to a connection, creating it as needed on demand; throw on failure
|
||||||
DBConnection &GetConnection();
|
DBConnection &GetConnection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -302,15 +302,17 @@ bool ProjectFileManager::DoSave(const FilePath & fileName, const bool fromSaveAs
|
|||||||
bool success = projectFileIO.SaveProject(fileName, mLastSavedTracks.get());
|
bool success = projectFileIO.SaveProject(fileName, mLastSavedTracks.get());
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
ShowErrorDialog(
|
// Show this error only if we didn't fail reconnection in SaveProject
|
||||||
&window,
|
if (projectFileIO.HasConnection())
|
||||||
XO("Error Saving Project"),
|
ShowErrorDialog(
|
||||||
XO("Could not save project. Perhaps %s \n"
|
&window,
|
||||||
"is not writable or the disk is full.\n"
|
XO("Error Saving Project"),
|
||||||
"For tips on freeing up space, click the help button.")
|
XO("Could not save project. Perhaps %s \n"
|
||||||
.Format(fileName),
|
"is not writable or the disk is full.\n"
|
||||||
"Error:_Disk_full_or_not_writable"
|
"For tips on freeing up space, click the help button.")
|
||||||
);
|
.Format(fileName),
|
||||||
|
"Error:_Disk_full_or_not_writable"
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,8 @@ ProjectManager::ProjectManager( AudacityProject &project )
|
|||||||
window.Bind( wxEVT_CLOSE_WINDOW, &ProjectManager::OnCloseWindow, this );
|
window.Bind( wxEVT_CLOSE_WINDOW, &ProjectManager::OnCloseWindow, this );
|
||||||
mProject.Bind(EVT_PROJECT_STATUS_UPDATE,
|
mProject.Bind(EVT_PROJECT_STATUS_UPDATE,
|
||||||
&ProjectManager::OnStatusChange, this);
|
&ProjectManager::OnStatusChange, this);
|
||||||
|
project.Bind( EVT_RECONNECTION_FAILURE,
|
||||||
|
&ProjectManager::OnReconnectionFailure, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectManager::~ProjectManager() = default;
|
ProjectManager::~ProjectManager() = default;
|
||||||
@ -589,6 +591,14 @@ AudacityProject *ProjectManager::New()
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectManager::OnReconnectionFailure(wxCommandEvent & event)
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
wxTheApp->CallAfter([this]{
|
||||||
|
ProjectWindow::Get(mProject).Close(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectManager::OnCloseWindow(wxCloseEvent & event)
|
void ProjectManager::OnCloseWindow(wxCloseEvent & event)
|
||||||
{
|
{
|
||||||
auto &project = mProject;
|
auto &project = mProject;
|
||||||
|
@ -65,6 +65,7 @@ public:
|
|||||||
void SetSkipSavePrompt(bool bSkip) { sbSkipPromptingForSave = bSkip; };
|
void SetSkipSavePrompt(bool bSkip) { sbSkipPromptingForSave = bSkip; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void OnReconnectionFailure(wxCommandEvent & event);
|
||||||
void OnCloseWindow(wxCloseEvent & event);
|
void OnCloseWindow(wxCloseEvent & event);
|
||||||
void OnTimer(wxTimerEvent & event);
|
void OnTimer(wxTimerEvent & event);
|
||||||
void OnOpenAudioFile(wxCommandEvent & event);
|
void OnOpenAudioFile(wxCommandEvent & event);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user