mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
Implement a cache for BibTeX data. There was a cache of sorts already in InsetCitation, but that was being used only to cache the labels. So that has been moved to Buffer, and everything else that needs access to BibTeX data should call either Buffer::localBibInfo(), which gives you the BiblioInfo for this Buffer, or Buffer::masterBibInfo(), which gives you the BiblioInfo for the Buffer's master, if it has one, or for it, otherwise. Normally, what you want is masterBibInfo().
Thanks to Andre for help with linking problems. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@24505 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
45eee3cbbb
commit
2193a50605
@ -43,16 +43,11 @@ namespace lyx {
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
BibTeXInfo::BibTeXInfo(bool ib)
|
||||
: is_bibtex_(ib)
|
||||
{}
|
||||
|
||||
|
||||
BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type)
|
||||
: is_bibtex_(true), bib_key_(key), entry_type_(type)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
bool BibTeXInfo::hasField(docstring const & field) const
|
||||
{
|
||||
return count(field) == 1;
|
||||
@ -75,7 +70,7 @@ docstring const & BibTeXInfo::getValueForField(string const & field) const
|
||||
}
|
||||
|
||||
|
||||
static docstring familyName(docstring const & name)
|
||||
docstring familyName(docstring const & name)
|
||||
{
|
||||
if (name.empty())
|
||||
return docstring();
|
||||
@ -416,19 +411,9 @@ vector<docstring> const BiblioInfo::getAuthorYearStrings(
|
||||
}
|
||||
|
||||
|
||||
void BiblioInfo::fillWithBibKeys(Buffer const * const buf)
|
||||
{
|
||||
/// if this is a child document and the parent is already loaded
|
||||
/// use the parent's list instead [ale990412]
|
||||
Buffer const * const tmp = buf->masterBuffer();
|
||||
LASSERT(tmp, return);
|
||||
if (tmp != buf) {
|
||||
this->fillWithBibKeys(tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
for (InsetIterator it = inset_iterator_begin(buf->inset()); it; ++it)
|
||||
it->fillWithBibKeys(*this, it);
|
||||
void BiblioInfo::mergeBiblioInfo(BiblioInfo const & info)
|
||||
{
|
||||
bimap_.insert(info.begin(), info.end());
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,9 +44,11 @@ class BibTeXInfo {
|
||||
public:
|
||||
///
|
||||
typedef std::map<docstring, docstring>::const_iterator const_iterator;
|
||||
///
|
||||
BibTeXInfo() : is_bibtex_(true) {}
|
||||
/// argument sets isBibTeX_, so should be false only if it's coming
|
||||
/// from a bibliography environment
|
||||
BibTeXInfo(bool ib = true);
|
||||
BibTeXInfo(bool ib) : is_bibtex_(ib) {}
|
||||
/// constructor that sets the entryType
|
||||
BibTeXInfo(docstring const & key, docstring const & type);
|
||||
/// Search for the given field and return the associated info.
|
||||
@ -106,9 +108,6 @@ public:
|
||||
std::vector<docstring> const getFields() const;
|
||||
/// Returns a sorted vector of BibTeX entry types in use
|
||||
std::vector<docstring> const getEntries() const;
|
||||
/// Fills keys with BibTeX information derived from the various insets
|
||||
/// in a given buffer, in its master document.
|
||||
void fillWithBibKeys(Buffer const * const buf);
|
||||
/// return the short form of an authorlist
|
||||
docstring const getAbbreviatedAuthor(docstring const & key) const;
|
||||
/// return the year from the bibtex data record
|
||||
@ -157,6 +156,8 @@ public:
|
||||
///
|
||||
const_iterator find(docstring const & f) const { return bimap_.find(f); }
|
||||
///
|
||||
void mergeBiblioInfo(BiblioInfo const & info);
|
||||
///
|
||||
BibTeXInfo & operator[](docstring const & f) { return bimap_[f]; }
|
||||
///
|
||||
void addFieldName(docstring const & f) { field_names_.insert(f); }
|
||||
|
@ -204,6 +204,9 @@ public:
|
||||
/// documents), needed for appropriate update of natbib labels.
|
||||
mutable support::FileNameList bibfilesCache_;
|
||||
|
||||
/// A cache for bibliography info
|
||||
mutable BiblioInfo bibinfo_;
|
||||
|
||||
mutable RefCache ref_cache_;
|
||||
|
||||
/// our Text that should be wrapped in an InsetText
|
||||
@ -233,8 +236,8 @@ static FileName createBufferTmpDir()
|
||||
Buffer::Impl::Impl(Buffer & parent, FileName const & file, bool readonly_)
|
||||
: parent_buffer(0), lyx_clean(true), bak_clean(true), unnamed(false),
|
||||
read_only(readonly_), filename(file), file_fully_loaded(false),
|
||||
toc_backend(&parent), macro_lock(false),
|
||||
timestamp_(0), checksum_(0), wa_(0), undo_(parent)
|
||||
toc_backend(&parent), macro_lock(false), timestamp_(0),
|
||||
checksum_(0), wa_(0), undo_(parent)
|
||||
{
|
||||
temppath = createBufferTmpDir();
|
||||
lyxvc.setBuffer(&parent);
|
||||
@ -1343,6 +1346,45 @@ support::FileNameList const & Buffer::getBibfilesCache() const
|
||||
}
|
||||
|
||||
|
||||
BiblioInfo const & Buffer::masterBibInfo() const
|
||||
{
|
||||
// if this is a child document and the parent is already loaded
|
||||
// use the parent's list instead [ale990412]
|
||||
Buffer const * const tmp = masterBuffer();
|
||||
LASSERT(tmp, /**/);
|
||||
if (tmp != this)
|
||||
return tmp->masterBibInfo();
|
||||
return localBibInfo();
|
||||
}
|
||||
|
||||
|
||||
BiblioInfo const & Buffer::localBibInfo() const
|
||||
{
|
||||
// cache the timestamp of the bibliography files.
|
||||
static map<FileName, time_t> bibfileStatus;
|
||||
|
||||
support::FileNameList const & bibfilesCache = getBibfilesCache();
|
||||
// compare the cached timestamps with the actual ones.
|
||||
bool changed = false;
|
||||
support::FileNameList::const_iterator ei = bibfilesCache.begin();
|
||||
support::FileNameList::const_iterator en = bibfilesCache.end();
|
||||
for (; ei != en; ++ ei) {
|
||||
time_t lastw = ei->lastModified();
|
||||
if (lastw != bibfileStatus[*ei]) {
|
||||
changed = true;
|
||||
bibfileStatus[*ei] = lastw;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it)
|
||||
it->fillWithBibKeys(d->bibinfo_, it);
|
||||
}
|
||||
return d->bibinfo_;
|
||||
}
|
||||
|
||||
|
||||
bool Buffer::isDepClean(string const & name) const
|
||||
{
|
||||
DepClean::const_iterator const it = d->dep_clean.find(name);
|
||||
@ -1978,8 +2020,7 @@ void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to,
|
||||
// Check if the label 'from' appears more than once
|
||||
vector<docstring> labels;
|
||||
string paramName;
|
||||
BiblioInfo keys;
|
||||
keys.fillWithBibKeys(this);
|
||||
BiblioInfo const & keys = masterBibInfo();
|
||||
BiblioInfo::const_iterator bit = keys.begin();
|
||||
BiblioInfo::const_iterator bend = keys.end();
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
namespace lyx {
|
||||
|
||||
class BiblioInfo;
|
||||
class BufferParams;
|
||||
class DocIterator;
|
||||
class ErrorItem;
|
||||
@ -308,6 +309,11 @@ public:
|
||||
/// Return the cache with all bibfiles in use (including bibfiles
|
||||
/// of loaded child documents).
|
||||
support::FileNameList const & getBibfilesCache() const;
|
||||
/// \return the bibliography information for this buffer's master,
|
||||
/// or just for it, if it isn't a child.
|
||||
BiblioInfo const & masterBibInfo() const;
|
||||
/// \return the bibliography information for this buffer ONLY.
|
||||
BiblioInfo const & localBibInfo() const;
|
||||
///
|
||||
void getLabelList(std::vector<docstring> &) const;
|
||||
|
||||
|
@ -61,6 +61,8 @@ endif
|
||||
lyx_SOURCES = \
|
||||
main.cpp \
|
||||
$(ASPELL) $(PSPELL) $(ISPELL) SpellBase.cpp \
|
||||
BiblioInfo.h \
|
||||
BiblioInfo.cpp \
|
||||
Box.cpp \
|
||||
Box.h \
|
||||
Dimension.cpp \
|
||||
@ -76,7 +78,6 @@ endif
|
||||
|
||||
SOURCEFILESCORE = \
|
||||
Author.cpp \
|
||||
BiblioInfo.cpp \
|
||||
Bidi.cpp \
|
||||
boost.cpp \
|
||||
BranchList.cpp \
|
||||
@ -169,7 +170,6 @@ SOURCEFILESCORE = \
|
||||
|
||||
HEADERFILESCORE = \
|
||||
Author.h \
|
||||
BiblioInfo.h \
|
||||
Bidi.h \
|
||||
BranchList.h \
|
||||
buffer_funcs.h \
|
||||
|
@ -599,7 +599,7 @@ QStringList GuiCitation::getEntriesAsQStringList()
|
||||
QStringList GuiCitation::citationStyles(int sel)
|
||||
{
|
||||
docstring const key = qstring_to_ucs4(cited_keys_[sel]);
|
||||
return to_qstring_list(bibkeysInfo_.getCiteStrings(key, buffer()));
|
||||
return to_qstring_list(bibInfo().getCiteStrings(key, buffer()));
|
||||
}
|
||||
|
||||
|
||||
@ -619,7 +619,6 @@ bool GuiCitation::initialiseParams(string const & data)
|
||||
{
|
||||
InsetCommand::string2params("citation", data, params_);
|
||||
CiteEngine const engine = buffer().params().citeEngine();
|
||||
bibkeysInfo_.fillWithBibKeys(&buffer());
|
||||
citeStyles_ = citeStyles(engine);
|
||||
return true;
|
||||
}
|
||||
@ -628,25 +627,24 @@ bool GuiCitation::initialiseParams(string const & data)
|
||||
void GuiCitation::clearParams()
|
||||
{
|
||||
params_.clear();
|
||||
bibkeysInfo_.clear();
|
||||
}
|
||||
|
||||
|
||||
vector<docstring> GuiCitation::availableKeys() const
|
||||
{
|
||||
return bibkeysInfo_.getKeys();
|
||||
return bibInfo().getKeys();
|
||||
}
|
||||
|
||||
|
||||
vector<docstring> GuiCitation::availableFields() const
|
||||
{
|
||||
return bibkeysInfo_.getFields();
|
||||
return bibInfo().getFields();
|
||||
}
|
||||
|
||||
|
||||
vector<docstring> GuiCitation::availableEntries() const
|
||||
{
|
||||
return bibkeysInfo_.getEntries();
|
||||
return bibInfo().getEntries();
|
||||
}
|
||||
|
||||
|
||||
@ -662,8 +660,8 @@ void GuiCitation::filterByEntryType(
|
||||
vector<docstring> result;
|
||||
for (; it != end; ++it) {
|
||||
docstring const key = *it;
|
||||
BiblioInfo::const_iterator cit = bibkeysInfo_.find(key);
|
||||
if (cit == bibkeysInfo_.end())
|
||||
BiblioInfo::const_iterator cit = bibInfo().find(key);
|
||||
if (cit == bibInfo().end())
|
||||
continue;
|
||||
if (cit->second.entryType() == entry_type)
|
||||
result.push_back(key);
|
||||
@ -680,10 +678,10 @@ CiteEngine GuiCitation::citeEngine() const
|
||||
|
||||
docstring GuiCitation::getInfo(docstring const & key) const
|
||||
{
|
||||
if (bibkeysInfo_.empty())
|
||||
if (bibInfo().empty())
|
||||
return docstring();
|
||||
|
||||
return bibkeysInfo_.getInfo(key);
|
||||
return bibInfo().getInfo(key);
|
||||
}
|
||||
|
||||
|
||||
@ -740,8 +738,8 @@ vector<docstring> GuiCitation::searchKeys(
|
||||
vector<docstring>::const_iterator it = keys_to_search.begin();
|
||||
vector<docstring>::const_iterator end = keys_to_search.end();
|
||||
for (; it != end; ++it ) {
|
||||
BiblioInfo::const_iterator info = bibkeysInfo_.find(*it);
|
||||
if (info == bibkeysInfo_.end())
|
||||
BiblioInfo::const_iterator info = bibInfo().find(*it);
|
||||
if (info == bibInfo().end())
|
||||
continue;
|
||||
|
||||
BibTeXInfo const & kvm = info->second;
|
||||
@ -776,6 +774,12 @@ void GuiCitation::dispatchParams()
|
||||
}
|
||||
|
||||
|
||||
BiblioInfo const & GuiCitation::bibInfo() const
|
||||
{
|
||||
return buffer().masterBibInfo();
|
||||
}
|
||||
|
||||
|
||||
Dialog * createGuiCitation(GuiView & lv) { return new GuiCitation(lv); }
|
||||
|
||||
|
||||
|
@ -186,7 +186,7 @@ private:
|
||||
|
||||
private:
|
||||
/// The BibTeX information available to the dialog
|
||||
BiblioInfo bibkeysInfo_;
|
||||
BiblioInfo const & bibInfo() const;
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
@ -66,9 +66,7 @@ void InsetBibitem::updateCommand(docstring const & new_key, bool)
|
||||
docstring const old_key = getParam("key");
|
||||
docstring key = new_key;
|
||||
|
||||
BiblioInfo keys;
|
||||
keys.fillWithBibKeys(&buffer());
|
||||
vector<docstring> bibkeys = keys.getKeys();
|
||||
vector<docstring> bibkeys = buffer().masterBibInfo().getKeys();
|
||||
|
||||
int i = 1;
|
||||
|
||||
|
@ -137,37 +137,7 @@ docstring complexLabel(Buffer const & buffer,
|
||||
if (!buffer.isFullyLoaded())
|
||||
return docstring();
|
||||
|
||||
// Cache the labels
|
||||
typedef map<Buffer const *, BiblioInfo> CachedMap;
|
||||
static CachedMap cached_keys;
|
||||
|
||||
// and cache the timestamp of the bibliography files.
|
||||
static map<FileName, time_t> bibfileStatus;
|
||||
|
||||
BiblioInfo biblist;
|
||||
|
||||
support::FileNameList const & bibfilesCache = buffer.getBibfilesCache();
|
||||
// compare the cached timestamps with the actual ones.
|
||||
bool changed = false;
|
||||
support::FileNameList::const_iterator ei = bibfilesCache.begin();
|
||||
support::FileNameList::const_iterator en = bibfilesCache.end();
|
||||
for (; ei != en; ++ ei) {
|
||||
time_t lastw = ei->lastModified();
|
||||
if (lastw != bibfileStatus[*ei]) {
|
||||
changed = true;
|
||||
bibfileStatus[*ei] = lastw;
|
||||
}
|
||||
}
|
||||
|
||||
// build the list only if the bibfiles have been changed
|
||||
if (cached_keys[&buffer].empty() || bibfileStatus.empty() || changed) {
|
||||
biblist.fillWithBibKeys(&buffer);
|
||||
cached_keys[&buffer] = biblist;
|
||||
} else {
|
||||
// use the cached keys
|
||||
biblist = cached_keys[&buffer];
|
||||
}
|
||||
|
||||
BiblioInfo const & biblist = buffer.masterBibInfo();
|
||||
if (biblist.empty())
|
||||
return docstring();
|
||||
|
||||
|
@ -685,10 +685,8 @@ void InsetInclude::fillWithBibKeys(BiblioInfo & keys,
|
||||
if (loadIfNeeded(buffer(), params())) {
|
||||
string const included_file = includedFilename(buffer(), params()).absFilename();
|
||||
Buffer * tmp = theBufferList().getBuffer(included_file);
|
||||
//FIXME This is kind of a dirty hack and should be made reasonable.
|
||||
tmp->setParent(0);
|
||||
keys.fillWithBibKeys(tmp);
|
||||
tmp->setParent(&buffer());
|
||||
BiblioInfo const & newkeys = tmp->localBibInfo();
|
||||
keys.mergeBiblioInfo(newkeys);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user