Jean-Marc Lasgouttes wrote: > Could you provide a 1.4 version so that I take a look?
attached. Jürgen > JMarc
Index: src/insets/insetbibtex.C =================================================================== --- src/insets/insetbibtex.C (Revision 13775) +++ src/insets/insetbibtex.C (Arbeitskopie) @@ -85,9 +85,10 @@ void InsetBibtex::doDispatch(LCursor & c case LFUN_INSET_MODIFY: { InsetCommandParams p; InsetCommandMailer::string2params("bibtex", cmd.argument, p); - if (!p.getCmdName().empty()) + if (!p.getCmdName().empty()) { setParams(p); - else + cur.buffer().updateBibfilesCache(); + } else cur.noUpdate(); break; } Index: src/insets/insetinclude.h =================================================================== --- src/insets/insetinclude.h (Revision 13775) +++ src/insets/insetinclude.h (Arbeitskopie) @@ -52,9 +52,19 @@ public: * \param buffer the Buffer containing this inset. * \param keys the list of bibkeys in the child buffer. */ - /// void fillWithBibKeys(Buffer const & buffer, std::vector<std::pair<std::string,std::string> > & keys) const; + /** Update the cache with all bibfiles in use of the child buffer + * (including bibfiles of grandchild documents). + * \param buffer the Buffer containing this inset. + */ + void updateBibfilesCache(Buffer const & buffer); + /** Return the cache with all bibfiles in use of the child buffer + * (including bibfiles of grandchild documents). + * \param buffer the Buffer containing this inset. + */ + std::vector<std::string> const & + getBibfilesCache(Buffer const & buffer) const; /// EDITABLE editable() const { return IS_EDITABLE; } /// Index: src/insets/insetinclude.C =================================================================== --- src/insets/insetinclude.C (Revision 13775) +++ src/insets/insetinclude.C (Arbeitskopie) @@ -128,9 +128,10 @@ void InsetInclude::doDispatch(LCursor & case LFUN_INSET_MODIFY: { InsetCommandParams p; InsetIncludeMailer::string2params(cmd.argument, p); - if (!p.getCmdName().empty()) + if (!p.getCmdName().empty()) { set(p, cur.buffer()); - else + cur.buffer().updateBibfilesCache(); + } else cur.noUpdate(); break; } @@ -613,6 +614,34 @@ void InsetInclude::fillWithBibKeys(Buffe } +void InsetInclude::updateBibfilesCache(Buffer const & buffer) +{ + if (loadIfNeeded(buffer, params_)) { + string const included_file = includedFilename(buffer, params_); + Buffer * tmp = bufferlist.getBuffer(included_file); + tmp->setParentName(""); + tmp->updateBibfilesCache(); + tmp->setParentName(parentFilename(buffer)); + } +} + + +std::vector<string> const & +InsetInclude::getBibfilesCache(Buffer const & buffer) const +{ + if (loadIfNeeded(buffer, params_)) { + string const included_file = includedFilename(buffer, params_); + Buffer * tmp = bufferlist.getBuffer(included_file); + tmp->setParentName(""); + std::vector<string> const & cache = tmp->getBibfilesCache(); + tmp->setParentName(parentFilename(buffer)); + return cache; + } + static std::vector<string> const empty; + return empty; +} + + void InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const { BOOST_ASSERT(mi.base.bv && mi.base.bv->buffer()); Index: src/insets/insetcite.C =================================================================== --- src/insets/insetcite.C (Revision 13775) +++ src/insets/insetcite.C (Arbeitskopie) @@ -24,6 +24,8 @@ #include "support/lstrings.h" +#include <boost/filesystem/operations.hpp> + using lyx::support::ascii_lowercase; using lyx::support::contains; using lyx::support::getVectorFromString; @@ -37,6 +39,7 @@ using std::vector; using std::map; namespace biblio = lyx::biblio; +namespace fs = boost::filesystem; namespace { @@ -50,26 +53,47 @@ string const getNatbibLabel(Buffer const if (!buffer.fully_loaded()) return string(); + // Cache the labels typedef std::map<Buffer const *, biblio::InfoMap> CachedMap; static CachedMap cached_keys; - // build the keylist - typedef vector<std::pair<string, string> > InfoType; - InfoType bibkeys; - buffer.fillWithBibKeys(bibkeys); - - InfoType::const_iterator bit = bibkeys.begin(); - InfoType::const_iterator bend = bibkeys.end(); + // and cache the timestamp of the bibliography files. + static std::map<string, time_t> bibfileStatus; biblio::InfoMap infomap; - for (; bit != bend; ++bit) { - infomap[bit->first] = bit->second; + + vector<string> const & bibfilesCache = buffer.getBibfilesCache(); + // compare the cached timestamps with the actual ones. + bool changed = false; + for (vector<string>::const_iterator it = bibfilesCache.begin(); + it != bibfilesCache.end(); ++ it) { + string const f = *it; + if (bibfileStatus[f] != fs::last_write_time(f)) { + changed = true; + bibfileStatus[f] = fs::last_write_time(f); + } } + + // build the keylist only if the bibfiles have been changed + if (cached_keys.empty() || bibfileStatus.empty() || changed) { + typedef vector<std::pair<string, string> > InfoType; + InfoType bibkeys; + buffer.fillWithBibKeys(bibkeys); + + InfoType::const_iterator bit = bibkeys.begin(); + InfoType::const_iterator bend = bibkeys.end(); + + for (; bit != bend; ++bit) + infomap[bit->first] = bit->second; + + cached_keys[&buffer] = infomap; + } else + // use the cached keys + infomap = cached_keys[&buffer]; + if (infomap.empty()) return string(); - cached_keys[&buffer] = infomap; - // the natbib citation-styles // CITET: author (year) // CITEP: (author,year) Index: src/BufferView_pimpl.C =================================================================== --- src/BufferView_pimpl.C (Revision 13775) +++ src/BufferView_pimpl.C (Arbeitskopie) @@ -1291,8 +1291,10 @@ bool BufferView::Pimpl::dispatch(FuncReq bv_funcs::findInset(tmpcur, InsetBase::BIBTEX_CODE, false); InsetBibtex * inset = getInsetByCode<InsetBibtex>(tmpcur, InsetBase::BIBTEX_CODE); - if (inset) - inset->addDatabase(cmd.argument); + if (inset) { + if (inset->addDatabase(cmd.argument)) + buffer_->updateBibfilesCache(); + } break; } @@ -1301,8 +1303,10 @@ bool BufferView::Pimpl::dispatch(FuncReq bv_funcs::findInset(tmpcur, InsetBase::BIBTEX_CODE, false); InsetBibtex * inset = getInsetByCode<InsetBibtex>(tmpcur, InsetBase::BIBTEX_CODE); - if (inset) - inset->delDatabase(cmd.argument); + if (inset) { + if (inset->delDatabase(cmd.argument)) + buffer_->updateBibfilesCache(); + } break; } Index: src/buffer.C =================================================================== --- src/buffer.C (Revision 13775) +++ src/buffer.C (Arbeitskopie) @@ -487,6 +487,7 @@ bool Buffer::readDocument(LyXLex & lex) for_each(text().paragraphs().begin(), text().paragraphs().end(), bind(&Paragraph::setInsetOwner, _1, &inset())); + updateBibfilesCache(); return res; } @@ -1253,6 +1254,53 @@ void Buffer::fillWithBibKeys(vector<pair } +void Buffer::updateBibfilesCache() +{ + // if this is a child document and the parent is already loaded + // update the parent's cache instead + Buffer * tmp = getMasterBuffer(); + BOOST_ASSERT(tmp); + if (tmp != this) { + tmp->updateBibfilesCache(); + return; + } + + bibfilesCache_.clear(); + for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) { + if (it->lyxCode() == InsetBase::BIBTEX_CODE) { + InsetBibtex const & inset = + dynamic_cast<InsetBibtex const &>(*it); + vector<string> const bibfiles = inset.getFiles(*this); + bibfilesCache_.insert(bibfilesCache_.end(), + bibfiles.begin(), + bibfiles.end()); + } else if (it->lyxCode() == InsetBase::INCLUDE_CODE) { + InsetInclude & inset = + dynamic_cast<InsetInclude &>(*it); + inset.updateBibfilesCache(*this); + vector<string> const & bibfiles = + inset.getBibfilesCache(*this); + bibfilesCache_.insert(bibfilesCache_.end(), + bibfiles.begin(), + bibfiles.end()); + } + } +} + + +vector<string> const & Buffer::getBibfilesCache() const +{ + // if this is a child document and the parent is already loaded + // use the parent's cache instead + Buffer const * tmp = getMasterBuffer(); + BOOST_ASSERT(tmp); + if (tmp != this) + return tmp->getBibfilesCache(); + + return bibfilesCache_; +} + + bool Buffer::isDepClean(string const & name) const { DepClean::const_iterator const it = pimpl_->dep_clean.find(name); @@ -1496,6 +1544,19 @@ Buffer const * Buffer::getMasterBuffer() } +Buffer * Buffer::getMasterBuffer() +{ + if (!params().parentname.empty() + && bufferlist.exists(params().parentname)) { + Buffer * buf = bufferlist.getBuffer(params().parentname); + if (buf) + return buf->getMasterBuffer(); + } + + return this; +} + + MacroData const & Buffer::getMacro(std::string const & name) const { return pimpl_->macros.get(name); Index: src/buffer.h =================================================================== --- src/buffer.h (Revision 13775) +++ src/buffer.h (Arbeitskopie) @@ -24,6 +24,7 @@ #include <boost/signal.hpp> #include <iosfwd> +#include <string> #include <map> #include <utility> #include <vector> @@ -217,6 +218,10 @@ public: child document) */ Buffer const * getMasterBuffer() const; + /** Get the document's master (or \c this if this is not a + child document) + */ + Buffer * getMasterBuffer(); /// Is buffer read-only? bool isReadonly() const; @@ -249,6 +254,12 @@ public: /// return all bibkeys from buffer and its childs void fillWithBibKeys(std::vector<std::pair<std::string, std::string> > & keys) const; + /// Update the cache with all bibfiles in use (including bibfiles + /// of child documents). + void updateBibfilesCache(); + /// Return the cache with all bibfiles in use (including bibfiles + /// of child documents). + std::vector<std::string> const & getBibfilesCache() const; /// void getLabelList(std::vector<std::string> &) const; @@ -352,6 +363,9 @@ private: /// it's BufferView, this should be FIXED in future. StableDocIterator cursor_; StableDocIterator anchor_; + /// A cache for the bibfiles (including bibfiles of child documents), + /// needed for appropriate update of natbib labels. + std::vector<std::string> bibfilesCache_; }; #endif