I have updated 4114 in response to Georg's suggestion. With the attached patch, lyx would ask for permission to overwrite a file when the file is externally modified.
The rest of the patch is untouched. Note that it uses timestamp before checksum so 'File->Revert to saved' should not cause any delay most of the time. OK to commit? Bo
Index: src/Buffer.h =================================================================== --- src/Buffer.h (revision 19374) +++ src/Buffer.h (working copy) @@ -209,6 +209,8 @@ bool isBakClean() const; /// bool isDepClean(std::string const & name) const; + /// whether or not disk file has been externally modified + bool isExternallyModified() const; /// mark the main lyx file as not needing saving void markClean() const; Index: src/LyXFunc.cpp =================================================================== --- src/LyXFunc.cpp (revision 19374) +++ src/LyXFunc.cpp (working copy) @@ -496,7 +496,8 @@ enable = buf->lyxvc().inUse(); break; case LFUN_BUFFER_RELOAD: - enable = !buf->isUnnamed() && !buf->isClean(); + enable = !buf->isUnnamed() && + (!buf->isClean() || buf->isExternallyModified()); break; case LFUN_INSET_SETTINGS: { Index: src/Buffer.cpp =================================================================== --- src/Buffer.cpp (revision 19374) +++ src/Buffer.cpp (working copy) @@ -103,6 +103,7 @@ using std::stack; using std::vector; using std::string; +using std::time_t; namespace lyx { @@ -131,6 +132,7 @@ using support::subst; using support::tempName; using support::trim; +using support::sum; namespace Alert = frontend::Alert; namespace os = support::os; @@ -192,13 +194,18 @@ /// Container for all sort of Buffer dependant errors. map<string, ErrorList> errorLists; + + /// timestamp and checksum used to test if the file has been externally + /// modified. (Used to properly enable 'File->Revert to saved', bug 4114). + time_t timestamp_; + unsigned long checksum_; }; Buffer::Impl::Impl(Buffer & parent, FileName const & file, bool readonly_) : lyx_clean(true), bak_clean(true), unnamed(false), read_only(readonly_), filename(file), file_fully_loaded(false), inset(params), - toc_backend(&parent) + timestamp_(0), checksum_(0), toc_backend(&parent) { inset.setAutoBreakRows(true); lyxvc.buffer(&parent); @@ -755,6 +762,9 @@ //MacroTable::localMacros().clear(); pimpl_->file_fully_loaded = true; + // save the timestamp and checksum of disk file + pimpl_->timestamp_ = fs::last_write_time(filename.toFilesystemEncoding()); + pimpl_->checksum_ = sum(filename); return success; } @@ -789,9 +799,22 @@ } } + // ask if the disk file has been externally modified + if (fs::exists(encodedFilename) && isExternallyModified()) { + docstring const file = makeDisplayPath(fileName(), 20); + docstring text = bformat(_("Document %1$s has been externally modified. Are you sure " + "you want to overwrite this file?"), file); + int const ret = Alert::prompt(_("Overwrite modified file?"), + text, 1, 1, _("&Overwrite"), _("&Cancel")); + if (ret == 1) + return false; + } + if (writeFile(pimpl_->filename)) { markClean(); removeAutosaveFile(fileName()); + pimpl_->timestamp_ = fs::last_write_time(pimpl_->filename.toFilesystemEncoding()); + pimpl_->checksum_ = sum(pimpl_->filename); return true; } else { // Saving failed, so backup is not backup @@ -1556,6 +1579,13 @@ } +bool Buffer::isExternallyModified() const +{ + return pimpl_->timestamp_ != fs::last_write_time(pimpl_->filename.toFilesystemEncoding()) + && pimpl_->checksum_ != sum(pimpl_->filename); +} + + void Buffer::markClean() const { if (!pimpl_->lyx_clean) { Index: lib/ui/stdmenus.inc =================================================================== --- lib/ui/stdmenus.inc (revision 19374) +++ lib/ui/stdmenus.inc (working copy) @@ -41,7 +41,7 @@ Item "Save|S" "buffer-write" Item "Save As...|A" "buffer-write-as" Item "Save All|l" "buffer-write-all" - Item "Revert|R" "buffer-reload" + Item "Revert to saved|R" "buffer-reload" Submenu "Version Control|V" "file_vc" Separator Submenu "Import|I" "file_import" Index: status.15x =================================================================== --- status.15x (revision 19374) +++ status.15x (working copy) @@ -40,14 +40,18 @@ * DOCUMENT INPUT/OUTPUT +- Check if the .lyx file has been externally modified when a buffer is saved. * USER INTERFACE: - Fix loading non-lyx child documents with relative path names, change - 'Load' to 'Edit' in the child document dialog. (Bug 4107 and 4111) + 'Load' to 'Edit' in the child document dialog. (Bugs 4107 and 4111) - Fix bug 4112: Do roman numerals beyond 20. +- Enable File -> Revert when the file is externally modified, and rename + this menu item to File -> Revert to saved. (Bugs 3766 and 4114) + * DOCUMENTATION