I filed this bug because I would like to have a better way to reload
externally modified .lyx file. Currently, one has to close and reopen
the file, or make the buffer dirty to use File->revert.

A long discussion about vim or emacs-like 'automatic reloading'
feature was fruitless, so I propose the following patch to enable
File->revert when the file is externally changed. This is not costly
because file checksum is only calculated when the File menu is
selected and when the file is saved/loaded, and is not intrusive
because no unwanted dialog will appear. I am happy with this solution
because it (partly) solves my problem.

Test
=====

1. open a lyx file
2. when buffer is clean, File -> revert is disabled.
3. externally modify the file, File -> revert is enabled so the buffer
can be reverted to disk file.

Patch
======

The patch

1. add checksum_ to Buffer::pimpl_ to store the checksum of the current buffer.

2. checksum_ is calculated when the buffer is loaded or saved in lyx.

3. Buffer::isExternallyModified() is added to test if file checksum
equals stored checksum_

4. File->revert is enabled if isExternallyModified() is true.

5. I like File->reload a lot better than File->revert so I also change
the menu name. This part can be removed if you guys like revert
better. Note, however, that the LFUN is actually named
LFUN_BUFFER_RELOAD.

Seeking two OKs.

Cheers,
Bo
Index: src/Buffer.h
===================================================================
--- src/Buffer.h	(revision 19356)
+++ 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 19356)
+++ src/LyXFunc.cpp	(working copy)
@@ -496,7 +496,7 @@
 		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: {
@@ -958,9 +958,9 @@
 			BOOST_ASSERT(lyx_view_ && lyx_view_->buffer());
 			docstring const file = makeDisplayPath(view()->buffer()->fileName(), 20);
 			docstring text = bformat(_("Any changes will be lost. Are you sure "
-							     "you want to revert to the saved version of the document %1$s?"), file);
-			int const ret = Alert::prompt(_("Revert to saved document?"),
-				text, 1, 1, _("&Revert"), _("&Cancel"));
+							     "you want to reload document %1$s from disk?"), file);
+			int const ret = Alert::prompt(_("Reload document from disk?"),
+				text, 1, 1, _("&Reload"), _("&Cancel"));
 
 			if (ret == 0)
 				reloadBuffer();
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp	(revision 19356)
+++ src/Buffer.cpp	(working copy)
@@ -131,6 +131,7 @@
 using support::subst;
 using support::tempName;
 using support::trim;
+using support::sum;
 
 namespace Alert = frontend::Alert;
 namespace os = support::os;
@@ -192,12 +193,15 @@
 
 	/// Container for all sort of Buffer dependant errors.
 	map<string, ErrorList> errorLists;
+
+	/// checksum used to test if the file has been changed externally
+	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),
+	  filename(file), file_fully_loaded(false), inset(params), checksum_(0),
 	  toc_backend(&parent)
 {
 	inset.setAutoBreakRows(true);
@@ -755,6 +759,7 @@
 	//MacroTable::localMacros().clear();
 
 	pimpl_->file_fully_loaded = true;
+	pimpl_->checksum_ = sum(filename);
 	return success;
 }
 
@@ -792,6 +797,7 @@
 	if (writeFile(pimpl_->filename)) {
 		markClean();
 		removeAutosaveFile(fileName());
+		pimpl_->checksum_ = sum(pimpl_->filename);
 		return true;
 	} else {
 		// Saving failed, so backup is not backup
@@ -1556,6 +1562,12 @@
 }
 
 
+bool Buffer::isExternallyModified() const
+{
+	return pimpl_->checksum_ != sum(pimpl_->filename);
+}
+
+
 void Buffer::markClean() const
 {
 	if (!pimpl_->lyx_clean) {
Index: lib/ui/stdmenus.inc
===================================================================
--- lib/ui/stdmenus.inc	(revision 19356)
+++ 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 "Reload|R" "buffer-reload"
 		Submenu "Version Control|V" "file_vc"
 		Separator
 		Submenu "Import|I" "file_import"

Reply via email to