Enable File -> Revert when the file is externally modified, rename this menu item to File -> Revert to saved, and check if the .lyx file has been externally modified when a buffer is saved. (Bugs 3766 and 4114)

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19380 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2007-08-09 20:46:22 +00:00
parent 04e2a40f5b
commit 95dbcd40f9
4 changed files with 56 additions and 3 deletions

View File

@ -41,7 +41,7 @@ Menuset
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"

View File

@ -103,6 +103,7 @@ using std::pair;
using std::stack;
using std::vector;
using std::string;
using std::time_t;
namespace lyx {
@ -131,6 +132,7 @@ using support::split;
using support::subst;
using support::tempName;
using support::trim;
using support::sum;
namespace Alert = frontend::Alert;
namespace os = support::os;
@ -192,13 +194,18 @@ public:
/// 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 @@ Buffer::ReadStatus Buffer::readFile(Lexer & lex, FileName const & filename,
//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 @@ bool Buffer::save() const
}
}
// ask if the disk file has been externally modified (use checksum method)
if (fs::exists(encodedFilename) && isExternallyModified(checksum_method)) {
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,16 @@ bool Buffer::isBakClean() const
}
bool Buffer::isExternallyModified(CheckMethod method) const
{
BOOST_ASSERT(fs::exists(pimpl_->filename.toFilesystemEncoding()));
// if method == timestamp, check timestamp before checksum
return (method == checksum_method
|| pimpl_->timestamp_ != fs::last_write_time(pimpl_->filename.toFilesystemEncoding()))
&& pimpl_->checksum_ != sum(pimpl_->filename);
}
void Buffer::markClean() const
{
if (!pimpl_->lyx_clean) {

View File

@ -83,6 +83,22 @@ public:
wrongversion ///< The version of the file does not match ours
};
/// Method to check if a file is externally modified, used by
/// isExternallyModified()
/**
* timestamp is fast but inaccurate. For example, the granularity
* of timestamp on a FAT filesystem is 2 second. Also, various operations
* may touch the timestamp of a file even when its content is unchanged.
*
* checksum is accurate but slow, which can be a problem when it is
* frequently used, or used for a large file on a slow (network) file
* system.
*/
enum CheckMethod {
checksum_method, ///< Use file check sum
timestamp_method, ///< Use timestamp, and checksum if timestamp has changed
};
/** Constructor
\param file
\param b optional \c false by default
@ -210,6 +226,9 @@ public:
///
bool isDepClean(std::string const & name) const;
/// whether or not disk file has been externally modified
bool isExternallyModified(CheckMethod method) const;
/// mark the main lyx file as not needing saving
void markClean() const;

View File

@ -496,7 +496,8 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
enable = buf->lyxvc().inUse();
break;
case LFUN_BUFFER_RELOAD:
enable = !buf->isUnnamed() && !buf->isClean();
enable = !buf->isUnnamed() && fs::exists(buf->fileName())
&& (!buf->isClean() || buf->isExternallyModified(Buffer::timestamp_method));
break;
case LFUN_INSET_SETTINGS: {