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