The attached patch deals with a UI bug that's been discussed here. The effect is this: If you try to open a file that is already open, LyX (i) checks if the buffer is dirty, and just switches buffers if it is not; (ii) if it is, you get this message:
The document %1$s is already loaded and has unsaved changes. Do you want to abandon your changes and reload the document? [Reload] [Keep Changes] If you hit the latter, you just get switched to the document.
The patch also fixes a bugs in this code which was revealed during testing: When you switch back to the document, if there were parse errors when it was loaded originally, they get displayed again. This is annoying. There was also a potential bug involving restoring the cursor position from session when returning to a file that is already open. This isn't actually a bug, because the session info seems to get saved constantly. But it's fragile.
There is no immediate need to commit this, as it's not a critical bug, but it's also quite safe, and there's a consensus this is a UI bug.
Richard -- ================================================================== Richard G Heck, Jr Professor of Philosophy Brown University http://frege.brown.edu/heck/ ================================================================== Get my public key from http://sks.keyserver.penguin.de Hash: 0x1DE91F1E66FFBDEC Learn how to sign your email using Thunderbird and GnuPG at: http://dudu.dyn.2-h.org/nist/gpg-enigmail-howto
Index: src/buffer_funcs.h =================================================================== --- src/buffer_funcs.h (revision 19273) +++ src/buffer_funcs.h (working copy) @@ -28,6 +28,12 @@ class TeXErrors; class ParIterator; + +/** + * Returns true if the file is already loaded into a buffer. + */ +bool checkIfLoaded(support::FileName const & fn); + /** * Loads a LyX file \c filename into \c Buffer * and \return success status. @@ -41,8 +47,8 @@ */ Buffer * checkAndLoadLyXFile(support::FileName const & filename); -/* Make a new file (buffer) with name \c filename based on a template - * named \c templatename +/** Make a new file (buffer) with name \c filename based on a template + * named \c templatename */ Buffer * newFile(std::string const & filename, std::string const & templatename, bool isNamed = false); Index: src/buffer_funcs.cpp =================================================================== --- src/buffer_funcs.cpp (revision 19273) +++ src/buffer_funcs.cpp (working copy) @@ -181,20 +181,29 @@ } +bool checkIfLoaded(FileName const & fn) +{ + return theBufferList().getBuffer(fn.absFilename()); +} + + Buffer * checkAndLoadLyXFile(FileName const & filename) { // File already open? - if (theBufferList().exists(filename.absFilename())) { + Buffer * checkBuffer = theBufferList().getBuffer(filename.absFilename()); + if (checkBuffer) { + if (checkBuffer->isClean()) + return checkBuffer; docstring const file = makeDisplayPath(filename.absFilename(), 20); - docstring text = bformat(_("The document %1$s is already " - "loaded.\n\nDo you want to revert " - "to the saved version?"), file); - if (Alert::prompt(_("Revert to saved document?"), - text, 0, 1, _("&Revert"), _("&Switch to document"))) - return theBufferList().getBuffer(filename.absFilename()); + docstring text = bformat(_( + "The document %1$s is already loaded and has unsaved changes.\n" + "Do you want to abandon your changes and reload the version on disk?"), file); + if (Alert::prompt(_("Reload saved document?"), + text, 0, 1, _("&Reload"), _("&Keep Changes"))) + return checkBuffer; // FIXME: should be LFUN_REVERT - if (theBufferList().close(theBufferList().getBuffer(filename.absFilename()), false)) + if (theBufferList().close(checkBuffer, false)) // Load it again. return checkAndLoadLyXFile(filename); else Index: src/frontends/LyXView.cpp =================================================================== --- src/frontends/LyXView.cpp (revision 19287) +++ src/frontends/LyXView.cpp (working copy) @@ -206,6 +206,7 @@ if (oldBuffer) parentfilename = oldBuffer->fileName(); + bool alreadyLoaded = checkIfLoaded(filename); Buffer * newBuffer = checkAndLoadLyXFile(filename); if (!newBuffer) { @@ -229,33 +230,35 @@ updateLabels(*newBuffer->getMasterBuffer()); bool const parse_error = !newBuffer->errorList("Parse").empty(); - if (parse_error || !auto_open) { + bool const need_switch = parse_error || !auto_open; + if (need_switch) { setBuffer(newBuffer, child_document); - showErrorList("Parse"); - } - - // scroll to the position when the file was last closed - if (!auto_open && lyxrc.use_lastfilepos) { - pit_type pit; - pos_type pos; - boost::tie(pit, pos) = LyX::ref().session().lastFilePos().load(filename); - // if successfully move to pit (returned par_id is not zero), - // update metrics and reset font - if (work_area_->bufferView().moveToPosition(pit, pos, 0, 0).get<1>()) { - if (work_area_->bufferView().fitCursor()) - work_area_->bufferView().updateMetrics(false); - newBuffer->text().setCurrentFont(work_area_->bufferView().cursor()); - updateMenubar(); - updateToolbars(); - updateLayoutChoice(); - updateStatusBar(); - work_area_->redraw(); + if (!alreadyLoaded) { + if (parse_error) + showErrorList("Parse"); + // scroll to the position when the file was last closed + if (lyxrc.use_lastfilepos) { + pit_type pit; + pos_type pos; + boost::tie(pit, pos) = LyX::ref().session().lastFilePos().load(filename); + // if successfully move to pit (returned par_id is not zero), + // update metrics and reset font + if (work_area_->bufferView().moveToPosition(pit, pos, 0, 0).get<1>()) { + if (work_area_->bufferView().fitCursor()) + work_area_->bufferView().updateMetrics(false); + newBuffer->text().setCurrentFont(work_area_->bufferView().cursor()); + updateMenubar(); + updateToolbars(); + updateLayoutChoice(); + updateStatusBar(); + work_area_->redraw(); + } + } + if (tolastfiles) + LyX::ref().session().lastFiles().add(filename); } } - if (tolastfiles) - LyX::ref().session().lastFiles().add(filename); - busy(false); return true; }