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;
 }

Reply via email to