mutable BiblioInfo bibinfo_;
/// whether the bibinfo cache is valid
mutable bool bibinfo_cache_valid_;
- /// whether the bibfile cache is valid
- mutable bool bibfile_cache_valid_;
/// Cache of timestamps of .bib files
map<FileName, time_t> bibfile_status_;
/// Indicates whether the bibinfo has changed since the last time
if (!cloned_buffer_ && parent_buffer && pb)
LYXERR0("Warning: a buffer should not have two parents!");
parent_buffer = pb;
- if (!cloned_buffer_ && parent_buffer) {
- parent_buffer->invalidateBibfileCache();
+ if (!cloned_buffer_ && parent_buffer)
parent_buffer->invalidateBibinfoCache();
- }
}
/// If non zero, this buffer is a clone of existing buffer \p cloned_buffer_
file_fully_loaded(false), file_format(LYX_FORMAT), need_format_backup(false),
ignore_parent(false), toc_backend(owner), macro_lock(false),
checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false),
- bibfile_cache_valid_(false), cite_labels_valid_(false), preview_error_(false),
+ cite_labels_valid_(false), preview_error_(false),
inset(0), preview_loader_(0), cloned_buffer_(cloned_buffer),
clone_list_(0), doing_export(false),
tracked_changes_present_(0), externally_modified_(false), parent_buffer(0),
bibfiles_cache_ = cloned_buffer_->d->bibfiles_cache_;
bibinfo_ = cloned_buffer_->d->bibinfo_;
bibinfo_cache_valid_ = cloned_buffer_->d->bibinfo_cache_valid_;
- bibfile_cache_valid_ = cloned_buffer_->d->bibfile_cache_valid_;
bibfile_status_ = cloned_buffer_->d->bibfile_status_;
cite_labels_valid_ = cloned_buffer_->d->cite_labels_valid_;
unnamed = cloned_buffer_->d->unnamed;
// Important: Keep the version formatting in sync with lyx2lyx and
// tex2lyx (bug 7951)
ofs << "#LyX " << lyx_version_major << "." << lyx_version_minor
- << " created this file. For more info see http://www.lyx.org/\n"
+ << " created this file. For more info see https://www.lyx.org/\n"
<< "\\lyxformat " << LYX_FORMAT << "\n"
<< "\\begin_document\n";
// first paragraph of the document. (Asger)
if (output_preamble && runparams.nice) {
os << "%% LyX " << lyx_version << " created this file. "
- "For more info, see http://www.lyx.org/.\n"
+ "For more info, see https://www.lyx.org/.\n"
"%% Do not edit unless you really know what "
"you are doing.\n";
}
// Biblatex bibliographies are loaded here
if (params().useBiblatex()) {
vector<docstring> const bibfiles =
- prepareBibFilePaths(runparams, getBibfilesCache(), true);
+ prepareBibFilePaths(runparams, getBibfiles(), true);
for (docstring const & file: bibfiles)
os << "\\addbibresource{" << file << "}\n";
}
os << from_ascii(tclass.class_header());
else if (runparams.flavor == OutputParams::XML)
os << "PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\" "
- << "\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\"";
+ << "\"https://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\"";
else
os << " PUBLIC \"-//OASIS//DTD DocBook V4.2//EN\"";
os << "<!-- " << ((runparams.flavor == OutputParams::XML)? "XML" : "SGML")
<< " file was created by LyX " << lyx_version
- << "\n See http://www.lyx.org/ for more information -->\n";
+ << "\n See https://www.lyx.org/ for more information -->\n";
params().documentClass().counters().reset();
}
-void Buffer::updateBibfilesCache(UpdateScope scope) const
-{
- // FIXME This is probably unnecssary, given where we call this.
- // If this is a child document, use the parent's cache instead.
- if (parent() && scope != UpdateChildOnly) {
- masterBuffer()->updateBibfilesCache();
- return;
- }
-
- d->bibfiles_cache_.clear();
- for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
- if (it->lyxCode() == BIBTEX_CODE) {
- InsetBibtex const & inset = static_cast<InsetBibtex const &>(*it);
- FileNamePairList const bibfiles = inset.getBibFiles();
- d->bibfiles_cache_.insert(d->bibfiles_cache_.end(),
- bibfiles.begin(),
- bibfiles.end());
- } else if (it->lyxCode() == INCLUDE_CODE) {
- InsetInclude & inset = static_cast<InsetInclude &>(*it);
- Buffer const * const incbuf = inset.getChildBuffer();
- if (!incbuf)
- continue;
- FileNamePairList const & bibfiles =
- incbuf->getBibfilesCache(UpdateChildOnly);
- if (!bibfiles.empty()) {
- d->bibfiles_cache_.insert(d->bibfiles_cache_.end(),
- bibfiles.begin(),
- bibfiles.end());
- }
- }
- }
- d->bibfile_cache_valid_ = true;
- d->bibinfo_cache_valid_ = false;
- d->cite_labels_valid_ = false;
-}
-
-
void Buffer::invalidateBibinfoCache() const
{
d->bibinfo_cache_valid_ = false;
d->cite_labels_valid_ = false;
+ removeBiblioTempFiles();
// also invalidate the cache for the parent buffer
Buffer const * const pbuf = d->parent();
if (pbuf)
}
-void Buffer::invalidateBibfileCache() const
-{
- d->bibfile_cache_valid_ = false;
- d->bibinfo_cache_valid_ = false;
- d->cite_labels_valid_ = false;
- // also invalidate the cache for the parent buffer
- Buffer const * const pbuf = d->parent();
- if (pbuf)
- pbuf->invalidateBibfileCache();
-}
-
-
-FileNamePairList const & Buffer::getBibfilesCache(UpdateScope scope) const
+FileNamePairList const & Buffer::getBibfiles(UpdateScope scope) const
{
// FIXME This is probably unnecessary, given where we call this.
- // If this is a child document, use the master's cache instead.
+ // If this is a child document, use the master instead.
Buffer const * const pbuf = masterBuffer();
if (pbuf != this && scope != UpdateChildOnly)
- return pbuf->getBibfilesCache();
-
- if (!d->bibfile_cache_valid_)
- this->updateBibfilesCache(scope);
-
+ return pbuf->getBibfiles();
return d->bibfiles_cache_;
}
}
+void Buffer::registerBibfiles(FileNamePairList const & bf) const {
+ Buffer const * const tmp = masterBuffer();
+ if (tmp != this)
+ return tmp->registerBibfiles(bf);
+
+ for (auto const & p : bf) {
+ FileNamePairList::const_iterator temp =
+ find(d->bibfiles_cache_.begin(), d->bibfiles_cache_.end(), p);
+ if (temp == d->bibfiles_cache_.end())
+ d->bibfiles_cache_.push_back(p);
+ }
+}
+
+
void Buffer::checkIfBibInfoCacheIsValid() const
{
// use the master's cache
return;
}
+ // if we already know the cache is invalid, no need to check
+ // the timestamps
+ if (!d->bibinfo_cache_valid_)
+ return;
+
// compare the cached timestamps with the actual ones.
- FileNamePairList const & bibfiles_cache = getBibfilesCache();
+ FileNamePairList const & bibfiles_cache = getBibfiles();
FileNamePairList::const_iterator ei = bibfiles_cache.begin();
FileNamePairList::const_iterator en = bibfiles_cache.end();
for (; ei != en; ++ ei) {
string const argument = to_utf8(func.argument());
// We'll set this back to false if need be.
bool dispatched = true;
- undo().beginUndoGroup();
+ // This handles undo groups automagically
+ UndoGroupHelper ugh(this);
switch (func.action()) {
case LFUN_BUFFER_TOGGLE_READ_ONLY:
}
case LFUN_BRANCH_ADD: {
- docstring branch_name = func.argument();
- if (branch_name.empty()) {
+ docstring branchnames = func.argument();
+ if (branchnames.empty()) {
dispatched = false;
break;
}
BranchList & branch_list = params().branchlist();
vector<docstring> const branches =
- getVectorFromString(branch_name, branch_list.separator());
+ getVectorFromString(branchnames, branch_list.separator());
docstring msg;
for (docstring const & branch_name : branches) {
Branch * branch = branch_list.find(branch_name);
break;
}
dr.dispatched(dispatched);
- undo().endUndoGroup();
}
std::set<Language const *> Buffer::getLanguages() const
{
- std::set<Language const *> languages;
- getLanguages(languages);
- return languages;
+ std::set<Language const *> langs;
+ getLanguages(langs);
+ return langs;
}
-void Buffer::getLanguages(std::set<Language const *> & languages) const
+void Buffer::getLanguages(std::set<Language const *> & langs) const
{
ParConstIterator end = par_iterator_end();
// add the buffer language, even if it's not actively used
- languages.insert(language());
+ langs.insert(language());
// iterate over the paragraphs
for (ParConstIterator it = par_iterator_begin(); it != end; ++it)
- it->getLanguages(languages);
+ it->getLanguages(langs);
// also children
ListOfBuffers clist = getDescendents();
for (auto const & cit : clist)
- cit->getLanguages(languages);
+ cit->getLanguages(langs);
}
}
d->bak_clean = false;
- DepClean::iterator it = d->dep_clean.begin();
- DepClean::const_iterator const end = d->dep_clean.end();
-
for (auto & depit : d->dep_clean)
depit.second = false;
}
// is it an external file?
if (insit.inset->lyxCode() == INCLUDE_CODE) {
// get buffer of external file
- InsetInclude const & inset =
+ InsetInclude const & incinset =
static_cast<InsetInclude const &>(*insit.inset);
macro_lock = true;
- Buffer * child = inset.getChildBuffer();
+ Buffer * child = incinset.getChildBuffer();
macro_lock = false;
if (!child)
continue;
// FIXME: There is a possibility of concurrent access to texrow
// here from the main GUI thread that should be securized.
d->cloned_buffer_->d->texrow = d->texrow;
- string const error_type = params().bufferFormat();
- d->cloned_buffer_->d->errorLists[error_type] = d->errorLists[error_type];
+ string const err_type = params().bufferFormat();
+ d->cloned_buffer_->d->errorLists[error_type] = d->errorLists[err_type];
}
Buffer const * const master = masterBuffer();
DocumentClass const & textclass = master->params().documentClass();
+ FileNamePairList old_bibfiles;
// do this only if we are the top-level Buffer
if (master == this) {
textclass.counters().reset(from_ascii("bibitem"));
reloadBibInfoCache();
+ // we will re-read this cache as we go through, but we need
+ // to know whether it's changed to know whether we need to
+ // update the bibinfo cache.
+ old_bibfiles = d->bibfiles_cache_;
+ d->bibfiles_cache_.clear();
}
// keep the buffers to be children in this set. If the call from the
// not updated during the updateBuffer call and TocModel::toc_ is invalid
// (bug 5699). The same happens if the master buffer is open in a different
// window. This test catches both possibilities.
- // See: http://marc.info/?l=lyx-devel&m=138590578911716&w=2
+ // See: https://marc.info/?l=lyx-devel&m=138590578911716&w=2
// There remains a problem here: If there is another child open in yet a third
// window, that TOC is not updated. So some more general solution is needed at
// some point.
ParIterator parit = cbuf.par_iterator_begin();
updateBuffer(parit, utype);
+ // If this document has siblings, then update the TocBackend later. The
+ // reason is to ensure that later siblings are up to date when e.g. the
+ // broken or not status of references is computed. The update is called
+ // in InsetInclude::addToToc.
if (master != this)
- // If this document has siblings, then update the TocBackend later. The
- // reason is to ensure that later siblings are up to date when e.g. the
- // broken or not status of references is computed. The update is called
- // in InsetInclude::addToToc.
return;
- d->bibinfo_cache_valid_ = true;
+ // if the bibfiles changed, the cache of bibinfo is invalid
+ sort(d->bibfiles_cache_.begin(), d->bibfiles_cache_.end());
+ // the old one should already be sorted
+ if (old_bibfiles != d->bibfiles_cache_) {
+ invalidateBibinfoCache();
+ reloadBibInfoCache();
+ // We relied upon the bibinfo cache when recalculating labels. But that
+ // cache was invalid, although we didn't find that out until now. So we
+ // have to do it all again.
+ // That said, the only thing we really need to do is update the citation
+ // labels. Nothing else will have changed. So we could create a new
+ // UpdateType that would signal that fact, if we needed to do so.
+ parit = cbuf.par_iterator_begin();
+ updateBuffer(parit, utype);
+ }
+ else
+ d->bibinfo_cache_valid_ = true;
d->cite_labels_valid_ = true;
/// FIXME: Perf
cbuf.tocBackend().update(true, utype);
Buffer::ReadStatus Buffer::reload()
{
setBusy(true);
- // c.f. bug http://www.lyx.org/trac/ticket/6587
+ // c.f. bug https://www.lyx.org/trac/ticket/6587
removeAutosaveFile();
// e.g., read-only status could have changed due to version control
d->filename.refresh();