diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/AutoSaver.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/AutoSaver.cpp')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/mptrack/AutoSaver.cpp | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/AutoSaver.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/AutoSaver.cpp new file mode 100644 index 00000000..c6eeac6d --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/mptrack/AutoSaver.cpp @@ -0,0 +1,190 @@ +/* + * AutoSaver.cpp + * ------------- + * Purpose: Class for automatically saving open modules at a specified interval. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "Mptrack.h" +#include "Mainfrm.h" +#include "Moddoc.h" +#include "AutoSaver.h" +#include "FileDialog.h" +#include "FolderScanner.h" +#include "resource.h" +#include "../soundlib/mod_specifications.h" +#include <algorithm> + + +OPENMPT_NAMESPACE_BEGIN + + +CAutoSaver::CAutoSaver() + : m_lastSave(timeGetTime()) +{ +} + + +bool CAutoSaver::IsEnabled() const +{ + return TrackerSettings::Instance().AutosaveEnabled; +} + +bool CAutoSaver::GetUseOriginalPath() const +{ + return TrackerSettings::Instance().AutosaveUseOriginalPath; +} + +mpt::PathString CAutoSaver::GetPath() const +{ + return TrackerSettings::Instance().AutosavePath.GetDefaultDir(); +} + +uint32 CAutoSaver::GetHistoryDepth() const +{ + return TrackerSettings::Instance().AutosaveHistoryDepth; +} + +uint32 CAutoSaver::GetSaveInterval() const +{ + return TrackerSettings::Instance().AutosaveIntervalMinutes; +} + + +bool CAutoSaver::DoSave(DWORD curTime) +{ + bool success = true; + + //If time to save and not already having save in progress. + if (CheckTimer(curTime) && !m_saveInProgress) + { + m_saveInProgress = true; + + theApp.BeginWaitCursor(); //display hour glass + + for(auto &modDoc : theApp.GetOpenDocuments()) + { + if(modDoc->ModifiedSinceLastAutosave()) + { + if(SaveSingleFile(*modDoc)) + { + CleanUpBackups(*modDoc); + } else + { + TrackerSettings::Instance().AutosaveEnabled = false; + Reporting::Warning("Warning: Auto Save failed and has been disabled. Please:\n- Review your Auto Save paths\n- Check available disk space and filesystem access rights"); + success = false; + } + } + } + + m_lastSave = timeGetTime(); + theApp.EndWaitCursor(); // End display hour glass + m_saveInProgress = false; + } + + return success; +} + + +bool CAutoSaver::CheckTimer(DWORD curTime) const +{ + return (curTime - m_lastSave) >= GetSaveIntervalMilliseconds(); +} + + +mpt::PathString CAutoSaver::GetBasePath(const CModDoc &modDoc, bool createPath) const +{ + mpt::PathString path; + if(GetUseOriginalPath()) + { + if(modDoc.m_bHasValidPath && !(path = modDoc.GetPathNameMpt()).empty()) + { + // File has a user-chosen path - remove filename + path = path.GetPath(); + } else + { + // if it doesn't, put it in settings dir + path = theApp.GetConfigPath() + P_("Autosave\\"); + if(createPath && !CreateDirectory(path.AsNative().c_str(), nullptr) && GetLastError() == ERROR_PATH_NOT_FOUND) + path = theApp.GetConfigPath(); + else if(!createPath && !path.IsDirectory()) + path = theApp.GetConfigPath(); + } + } else + { + path = GetPath(); + } + return path.EnsureTrailingSlash(); +} + + +mpt::PathString CAutoSaver::GetBaseName(const CModDoc &modDoc) const +{ + return mpt::PathString::FromCString(modDoc.GetTitle()).SanitizeComponent(); +} + + +mpt::PathString CAutoSaver::BuildFileName(const CModDoc &modDoc) const +{ + mpt::PathString name = GetBasePath(modDoc, true) + GetBaseName(modDoc); + const CString timeStamp = CTime::GetCurrentTime().Format(_T(".AutoSave.%Y%m%d.%H%M%S.")); + name += mpt::PathString::FromCString(timeStamp); //append backtup tag + timestamp + name += mpt::PathString::FromUTF8(modDoc.GetSoundFile().GetModSpecifications().fileExtension); + return name; +} + + +bool CAutoSaver::SaveSingleFile(CModDoc &modDoc) +{ + // We do not call CModDoc::DoSave as this populates the Recent Files + // list with backups... hence we have duplicated code.. :( + CSoundFile &sndFile = modDoc.GetSoundFile(); + + mpt::PathString fileName = BuildFileName(modDoc); + + // We are actually not going to show the log for autosaved files. + ScopedLogCapturer logcapturer(modDoc, _T(""), nullptr, false); + + bool success = false; + mpt::ofstream f(fileName, std::ios::binary); + if(f) + { + switch(modDoc.GetSoundFile().GetBestSaveFormat()) + { + case MOD_TYPE_MOD: success = sndFile.SaveMod(f); break; + case MOD_TYPE_S3M: success = sndFile.SaveS3M(f); break; + case MOD_TYPE_XM: success = sndFile.SaveXM(f); break; + case MOD_TYPE_IT: success = sndFile.SaveIT(f, fileName); break; + case MOD_TYPE_MPT: success = sndFile.SaveIT(f, fileName); break; + } + } + + return success; +} + + +void CAutoSaver::CleanUpBackups(const CModDoc &modDoc) const +{ + // Find all autosave files for this document, and delete the oldest ones if there are more than the user wants. + std::vector<mpt::PathString> foundfiles; + FolderScanner scanner(GetBasePath(modDoc, false), FolderScanner::kOnlyFiles, GetBaseName(modDoc) + P_(".AutoSave.*")); + mpt::PathString fileName; + while(scanner.Next(fileName)) + { + foundfiles.push_back(std::move(fileName)); + } + std::sort(foundfiles.begin(), foundfiles.end()); + size_t filesToDelete = std::max(static_cast<size_t>(GetHistoryDepth()), foundfiles.size()) - GetHistoryDepth(); + for(size_t i = 0; i < filesToDelete; i++) + { + DeleteFile(foundfiles[i].AsNative().c_str()); + } +} + + +OPENMPT_NAMESPACE_END |