diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp index 653ec1c15..fd15b4671 100644 --- a/aegisub/src/ass_file.cpp +++ b/aegisub/src/ass_file.cpp @@ -69,7 +69,7 @@ namespace std { /// @brief AssFile constructor AssFile::AssFile () -: commitId(-1) +: commitId(0) , loaded(false) { } @@ -152,9 +152,8 @@ void AssFile::Load(const wxString &_filename,wxString charset,bool addToRecent) UndoStack.clear(); RedoStack.clear(); undoDescription.clear(); - commitId = -1; - savedCommitId = 0; Commit("", COMMIT_NEW); + savedCommitId = commitId; // Add to recent if (addToRecent) AddToRecent(filename); @@ -181,6 +180,35 @@ void AssFile::Save(wxString filename, bool setfilename, bool addToRecent, wxStri } } +wxString AssFile::AutoSave() { + if (!loaded || commitId == autosavedCommitId) + return ""; + + wxFileName origfile(filename); + wxString path = lagi_wxString(OPT_GET("Path/Auto/Save")->GetString()); + if (!path) + path = origfile.GetPath(); + + wxFileName dstpath(path); + if (!dstpath.IsAbsolute()) + path = StandardPaths::DecodePathMaybeRelative(path, "?user/"); + dstpath.AssignDir(path); + if (!dstpath.DirExists()) + wxMkdir(path); + + wxString name = origfile.GetName(); + if (name.empty()) + dstpath.SetFullName("Untitled.AUTOSAVE.ass"); + else + dstpath.SetFullName(name + ".AUTOSAVE.ass"); + + Save(dstpath.GetFullPath(), false, false); + + autosavedCommitId = commitId; + + return dstpath.GetFullPath(); +} + void AssFile::SaveMemory(std::vector &dst,const wxString encoding) { // Set encoding wxString enc = encoding; @@ -420,8 +448,6 @@ void AssFile::Clear() { UndoStack.clear(); RedoStack.clear(); undoDescription.clear(); - commitId = -1; - savedCommitId = 0; } void AssFile::LoadDefault(bool defline) { @@ -747,7 +773,7 @@ int AssFile::Commit(wxString desc, int type, int amendId, AssEntry *single_line) ++commitId; // Allow coalescing only if it's the last change and the file has not been // saved since the last change - if (commitId == amendId+1 && RedoStack.empty() && savedCommitId != commitId) { + if (commitId == amendId+1 && RedoStack.empty() && savedCommitId+1 != commitId && autosavedCommitId+1 != commitId) { // If only one line changed just modify it instead of copying the file if (single_line) { entryIter this_it = Line.begin(), undo_it = UndoStack.back().Line.begin(); diff --git a/aegisub/src/ass_file.h b/aegisub/src/ass_file.h index 051191cad..322e8a28b 100644 --- a/aegisub/src/ass_file.h +++ b/aegisub/src/ass_file.h @@ -71,6 +71,8 @@ class AssFile { int commitId; /// Last saved version of this file int savedCommitId; + /// Last autosaved version of this file + int autosavedCommitId; /// A set of changes has been committed to the file (AssFile::CommitType) agi::signal::Signal AnnounceCommit; @@ -123,12 +125,18 @@ public: /// @param charset Character set of file or empty to autodetect /// @param addToRecent Should the file be added to the MRU list? void Load(const wxString &file,wxString charset="",bool addToRecent=true); + /// @brief Save to a file /// @param file Path to save to /// @param setfilename Should the filename be changed to the passed path? /// @param addToRecent Should the file be added to the MRU list? /// @param encoding Encoding to use, or empty to let the writer decide (which usually means "App/Save Charset") void Save(wxString file,bool setfilename=false,bool addToRecent=true,const wxString encoding=""); + + /// @brief Autosave the file if there have been any chances since the last autosave + /// @return File name used or empty if no save was performed + wxString AutoSave(); + /// @brief Save to a memory buffer. Used for subtitle providers which support it /// @param[out] dst Destination vector void SaveMemory(std::vector &dst,const wxString encoding=""); diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index 448ccfc06..77b1c922f 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -585,27 +585,9 @@ void FrameMain::OnCloseWindow (wxCloseEvent &event) { } void FrameMain::OnAutoSave(wxTimerEvent &) try { - if (context->ass->loaded && context->ass->IsModified()) { - wxFileName origfile(context->ass->filename); - wxString path = lagi_wxString(OPT_GET("Path/Auto/Save")->GetString()); - if (path.IsEmpty()) path = origfile.GetPath(); - wxFileName dstpath(path); - if (!dstpath.IsAbsolute()) path = StandardPaths::DecodePathMaybeRelative(path, "?user/"); - dstpath.AssignDir(path); - if (!dstpath.DirExists()) wxMkdir(path); - - wxString name = origfile.GetName(); - if (name.empty()) { - dstpath.SetFullName("Untitled.AUTOSAVE.ass"); - } - else { - dstpath.SetFullName(name + ".AUTOSAVE.ass"); - } - - context->ass->Save(dstpath.GetFullPath(),false,false); - - StatusTimeout(_("File backup saved as \"") + dstpath.GetFullPath() + "\"."); - } + wxString fn = context->ass->AutoSave(); + if (!fn.empty()) + StatusTimeout(wxString::Format(_("File backup saved as \"%s\"."), fn)); } catch (const agi::Exception& err) { StatusTimeout(lagi_wxString("Exception when attempting to autosave file: " + err.GetMessage()));