The attached patch is a first, simple fix for this bug: If a file fails to load, we do not try to load it again. The downside to this version is that, even if you fixed the problem, then it won't try to load again. I tried resetting the failedtoload_ variable in fileChanged(), but that didn't work, as it doesn't seem to get hit. I guess that doesn't get checked for child documents.
Note that most of this is moving certain methods into InsetInclude. rh
Index: src/insets/InsetInclude.cpp =================================================================== --- src/insets/InsetInclude.cpp (revision 27676) +++ src/insets/InsetInclude.cpp (working copy) @@ -160,7 +160,8 @@ InsetInclude::InsetInclude(InsetCommandParams const & p) : InsetCommand(p, "include"), include_label(uniqueID()), - preview_(new RenderMonitoredPreview(this)), set_label_(false), label_(0) + preview_(new RenderMonitoredPreview(this)), failedtoload_(false), + set_label_(false), label_(0) { preview_->fileChanged(boost::bind(&InsetInclude::fileChanged, this)); @@ -173,7 +174,8 @@ InsetInclude::InsetInclude(InsetInclude const & other) : InsetCommand(other), include_label(other.include_label), - preview_(new RenderMonitoredPreview(this)), set_label_(false), label_(0) + preview_(new RenderMonitoredPreview(this)), failedtoload_(false), + set_label_(false), label_(0) { preview_->fileChanged(boost::bind(&InsetInclude::fileChanged, this)); @@ -351,31 +353,34 @@ } -/// return the child buffer if the file is a LyX doc and is loaded -Buffer * getChildBuffer(Buffer const & buffer, InsetCommandParams const & params) +Buffer * InsetInclude::getChildBuffer(Buffer const & buffer) const { - if (isVerbatim(params) || isListings(params)) + InsetCommandParams const & p = params(); + if (isVerbatim(p) || isListings(p)) return 0; - string const included_file = includedFilename(buffer, params).absFilename(); + string const included_file = includedFilename(buffer, p).absFilename(); if (!isLyXFilename(included_file)) return 0; - Buffer * childBuffer = loadIfNeeded(buffer, params); + Buffer * childBuffer = loadIfNeeded(buffer); // FIXME: recursive includes return (childBuffer == &buffer) ? 0 : childBuffer; } -/// return true if the file is or got loaded. -Buffer * loadIfNeeded(Buffer const & parent, InsetCommandParams const & params) +Buffer * InsetInclude::loadIfNeeded(Buffer const & parent) const { - if (isVerbatim(params) || isListings(params)) + InsetCommandParams const & p = params(); + if (failedtoload_) return 0; + if (isVerbatim(p) || isListings(p)) + return 0; + string const parent_filename = parent.absFileName(); - FileName const included_file = makeAbsPath(to_utf8(params["filename"]), + FileName const included_file = makeAbsPath(to_utf8(p["filename"]), onlyPath(parent_filename)); if (!isLyXFilename(included_file.absFilename())) @@ -393,6 +398,7 @@ return 0; if (!child->loadLyXFile(included_file)) { + failedtoload_ = true; //close the buffer we just opened theBufferList().release(child); return 0; @@ -466,7 +472,7 @@ isLyXFilename(included_file.absFilename())) { //if it's a LyX file and we're inputting or including, //try to load it so we can write the associated latex - if (!loadIfNeeded(buffer(), params())) + if (!loadIfNeeded(buffer())) return false; Buffer * tmp = theBufferList().getBuffer(included_file); @@ -626,7 +632,7 @@ string const exportfile = changeExtension(incfile, ".sgml"); DocFileName writefile(changeExtension(included_file, ".sgml")); - if (loadIfNeeded(buffer(), params())) { + if (loadIfNeeded(buffer())) { Buffer * tmp = theBufferList().getBuffer(FileName(included_file)); string const mangled = writefile.mangledFilename(); @@ -689,7 +695,7 @@ // Here we must do the fun stuff... // Load the file in the include if it needs // to be loaded: - if (loadIfNeeded(buffer(), params())) { + if (loadIfNeeded(buffer())) { // a file got loaded Buffer * const tmp = theBufferList().getBuffer(FileName(included_file)); // make sure the buffer isn't us @@ -711,7 +717,7 @@ void InsetInclude::fillWithBibKeys(BiblioInfo & keys, InsetIterator const & /*di*/) const { - if (loadIfNeeded(buffer(), params())) { + if (loadIfNeeded(buffer())) { string const included_file = includedFilename(buffer(), params()).absFilename(); Buffer * tmp = theBufferList().getBuffer(FileName(included_file)); BiblioInfo const & newkeys = tmp->localBibInfo(); @@ -722,7 +728,7 @@ void InsetInclude::updateBibfilesCache() { - Buffer * const tmp = getChildBuffer(buffer(), params()); + Buffer * const tmp = getChildBuffer(buffer()); if (tmp) { tmp->setParent(0); tmp->updateBibfilesCache(); @@ -734,7 +740,7 @@ support::FileNameList const & InsetInclude::getBibfilesCache(Buffer const & buffer) const { - Buffer * const tmp = getChildBuffer(buffer, params()); + Buffer * const tmp = getChildBuffer(buffer); if (tmp) { tmp->setParent(0); support::FileNameList const & cache = tmp->getBibfilesCache(); @@ -813,6 +819,7 @@ if (!buffer) return; + failedtoload_ = false; preview_->removePreview(*buffer); add_preview(*preview_.get(), *this, *buffer); preview_->startLoading(*buffer); @@ -888,7 +895,7 @@ toc.push_back(TocItem(pit, 0, str)); return; } - Buffer const * const childbuffer = getChildBuffer(buffer(), params()); + Buffer const * const childbuffer = getChildBuffer(buffer()); if (!childbuffer) return; @@ -909,7 +916,7 @@ void InsetInclude::updateLabels(ParIterator const & it) { - Buffer const * const childbuffer = getChildBuffer(buffer(), params()); + Buffer const * const childbuffer = getChildBuffer(buffer()); if (childbuffer) { childbuffer->updateLabels(true); return; Index: src/insets/InsetInclude.h =================================================================== --- src/insets/InsetInclude.h (revision 27676) +++ src/insets/InsetInclude.h (working copy) @@ -95,6 +95,10 @@ static bool isCompatibleCommand(std::string const & s); /// docstring contextMenu(BufferView const & bv, int x, int y) const; + /// \return the child buffer if the file is a LyX doc and is loaded + Buffer * getChildBuffer(Buffer const & buffer) const; + /// \return loaded Buffer or zero if the file loading did not proceed. + Buffer * loadIfNeeded(Buffer const & parent) const; protected: InsetInclude(InsetInclude const &); /// @@ -121,6 +125,8 @@ /// The pointer never changes although *preview_'s contents may. boost::scoped_ptr<RenderMonitoredPreview> const preview_; + /// + mutable bool failedtoload_; /// cache mutable bool set_label_; mutable RenderButton button_; @@ -128,8 +134,6 @@ InsetLabel * label_; }; -/// return loaded Buffer or zero if the file loading did not proceed. -Buffer * loadIfNeeded(Buffer const & parent, InsetCommandParams const & params); } // namespace lyx Index: src/Buffer.cpp =================================================================== --- src/Buffer.cpp (revision 27676) +++ src/Buffer.cpp (working copy) @@ -1925,11 +1925,10 @@ // is it an external file? if (iit->inset->lyxCode() == INCLUDE_CODE) { // get buffer of external file - InsetCommand const & inset - = static_cast<InsetCommand const &>(*iit->inset); - InsetCommandParams const & ip = inset.params(); + InsetInclude const & inset + = static_cast<InsetInclude const &>(*iit->inset); d->macro_lock = true; - Buffer * child = loadIfNeeded(*this, ip); + Buffer * child = inset.loadIfNeeded(*this); d->macro_lock = false; if (!child) continue;