aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/mptrack/AutoSaver.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/AutoSaver.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-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.cpp190
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