http://bugzilla.lyx.org/show_bug.cgi?id=5514

With the new master_buffer param set, a child document checks if his master is 
already opened, and if not, it opens it (in the background) via 
checkAndLoadLyXFile.

The problem which triggers this bug is that checkAndLoadLyXFile checks if the 
file is already opened, and if so, if its buffer is dirty (which then brings 
up a question asking the user if he wants to abandon the changes and reload 
the file).

Now in the specific constellation of the bug, we do not only get loads of 
senseless popups (since the reloading reloads the child, which in turn reloads 
the master, etc.), but we finally end up with an invalid masterBuffer, if the 
user makes contradictionary choices.

The fix is simple: In the case of a child document looking for its master 
buffer, we do not have to care whether this master buffer is dirty or not, but 
only if it is available, and if not, open it.

Therefore I have added a bool to checkAndLoadLyXFile that skips the test for 
dirtyness and simply loads the master only if it is not already loaded. The 
bool is only used in this specific case, so there should be no surprises.

Thoughts?

Jürgen
Index: src/buffer_funcs.h
===================================================================
--- src/buffer_funcs.h	(Revision 27756)
+++ src/buffer_funcs.h	(Arbeitskopie)
@@ -27,7 +27,8 @@
  *  \retval the newly created \c Buffer pointer if successful or 0.
  *  \retval 0 if the \c Buffer could not be created.
  */
-Buffer * checkAndLoadLyXFile(support::FileName const & filename);
+Buffer * checkAndLoadLyXFile(support::FileName const & filename,
+		bool acceptDirty = false);
 
 /** Make a new file (buffer) with name \c filename based on a template
  *  named \c templatename
Index: src/buffer_funcs.cpp
===================================================================
--- src/buffer_funcs.cpp	(Revision 27756)
+++ src/buffer_funcs.cpp	(Arbeitskopie)
@@ -57,12 +57,15 @@
 namespace Alert = frontend::Alert;
 
 
-Buffer * checkAndLoadLyXFile(FileName const & filename)
+Buffer * checkAndLoadLyXFile(FileName const & filename, bool const acceptDirty)
 {
 	// File already open?
 	Buffer * checkBuffer = theBufferList().getBuffer(filename);
 	if (checkBuffer) {
-		if (checkBuffer->isClean())
+		// sometimes (when setting the master buffer from a child)
+		// we accept a dirty buffer right away (otherwise we'd get
+		// an infinite loop (bug 5514)
+		if (checkBuffer->isClean() || acceptDirty)
 			return checkBuffer;
 		docstring const file = makeDisplayPath(filename.absFilename(), 20);
 		docstring text = bformat(_(
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp	(Revision 27756)
+++ src/Buffer.cpp	(Arbeitskopie)
@@ -579,7 +579,7 @@
 		FileName const master_file = makeAbsPath(params().master,
 			   onlyPath(absFileName()));
 		if (isLyXFilename(master_file.absFilename())) {
-			Buffer * master = checkAndLoadLyXFile(master_file);
+			Buffer * master = checkAndLoadLyXFile(master_file, true);
 			d->parent_buffer = master;
 		}
 	}

Reply via email to