X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBuffer.cpp;h=a068ecfe3a9c9e502cac0801395b4aaf56f09a83;hb=0b17cb113523fb23c43064709e9b6606fe80914c;hp=98fdc287a6542f09d27f72ded17d4eadb7a6c5de;hpb=25e960b8fdaf05cebecada8decbb8adaf69deb07;p=lyx.git diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 98fdc287a6..a068ecfe3a 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -72,6 +72,7 @@ #include "insets/InsetInclude.h" #include "insets/InsetText.h" +#include "mathed/InsetMathHull.h" #include "mathed/MacroTable.h" #include "mathed/MathMacroTemplate.h" #include "mathed/MathSupport.h" @@ -126,7 +127,7 @@ namespace { // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -int const LYX_FORMAT = 390; // ps: forward view +int const LYX_FORMAT = 400; // uwestoehr: support for \rule typedef map DepClean; typedef map > RefCache; @@ -156,7 +157,7 @@ public: } delete inset; } - + /// search for macro in local (buffer) table or in children MacroData const * getBufferMacro(docstring const & name, DocIterator const & pos) const; @@ -254,7 +255,9 @@ public: /// A cache for bibliography info mutable BiblioInfo bibinfo_; /// whether the bibinfo cache is valid - bool bibinfo_cache_valid_; + mutable bool bibinfo_cache_valid_; + /// whether the bibfile cache is valid + mutable bool bibfile_cache_valid_; /// Cache of timestamps of .bib files map bibfile_status_; @@ -276,18 +279,27 @@ public: parent_buffer = 0; return parent_buffer; } + /// void setParent(Buffer const * pb) { - if (!cloned_buffer_ - && parent_buffer && pb && parent_buffer != pb) + if (parent_buffer == pb) + // nothing to do + return; + 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(); + parent_buffer->invalidateBibinfoCache(); + } } /// If non zero, this buffer is a clone of existing buffer \p cloned_buffer_ /// This one is useful for preview detached in a thread. Buffer const * cloned_buffer_; - + /// are we in the process of exporting this buffer? + mutable bool doing_export; + private: /// So we can force access via the accessors. mutable Buffer const * parent_buffer; @@ -320,7 +332,8 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_, read_only(readonly_), filename(file), file_fully_loaded(false), toc_backend(owner), macro_lock(false), timestamp_(0), checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false), - cloned_buffer_(cloned_buffer), parent_buffer(0) + bibfile_cache_valid_(false), cloned_buffer_(cloned_buffer), + doing_export(false), parent_buffer(0) { if (!cloned_buffer_) { temppath = createBufferTmpDir(); @@ -335,6 +348,7 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_, 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_; } @@ -403,7 +417,8 @@ Buffer::~Buffer() } // Remove any previewed LaTeX snippets associated with this buffer. - thePreviews().removeLoader(*this); + if (!isClone()) + thePreviews().removeLoader(*this); delete d; } @@ -1569,7 +1584,6 @@ void Buffer::writeLyXHTMLSource(odocstream & os, LaTeXFeatures features(*this, params(), runparams); validate(features); updateBuffer(UpdateMaster, OutputUpdate); - checkBibInfoCache(); d->bibinfo_.makeCitationLabels(*this); updateMacros(); updateMacroInstances(); @@ -1691,6 +1705,7 @@ void Buffer::getLabelList(vector & list) const 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. Buffer const * const pbuf = d->parent(); if (pbuf && scope != UpdateChildOnly) { @@ -1710,35 +1725,54 @@ void Buffer::updateBibfilesCache(UpdateScope scope) const } else if (it->lyxCode() == INCLUDE_CODE) { InsetInclude & inset = static_cast(*it); - inset.updateBibfilesCache(); + Buffer const * const incbuf = inset.getChildBuffer(); + if (!incbuf) + continue; support::FileNameList const & bibfiles = - inset.getBibfilesCache(); - d->bibfiles_cache_.insert(d->bibfiles_cache_.end(), - bibfiles.begin(), - bibfiles.end()); + incbuf->getBibfilesCache(UpdateChildOnly); + if (!bibfiles.empty()) { + d->bibfiles_cache_.insert(d->bibfiles_cache_.end(), + bibfiles.begin(), + bibfiles.end()); + } } } - // the bibinfo cache is now invalid + d->bibfile_cache_valid_ = true; d->bibinfo_cache_valid_ = false; } -void Buffer::invalidateBibinfoCache() +void Buffer::invalidateBibinfoCache() const { d->bibinfo_cache_valid_ = false; + // also invalidate the cache for the parent buffer + Buffer const * const pbuf = d->parent(); + if (pbuf) + pbuf->invalidateBibinfoCache(); } -support::FileNameList const & Buffer::getBibfilesCache(UpdateScope scope) const +void Buffer::invalidateBibfileCache() const { - // If this is a child document, use the parent's cache instead. + d->bibfile_cache_valid_ = false; + d->bibinfo_cache_valid_ = false; + // also invalidate the cache for the parent buffer Buffer const * const pbuf = d->parent(); - if (pbuf && scope != UpdateChildOnly) + if (pbuf) + pbuf->invalidateBibfileCache(); +} + + +support::FileNameList const & Buffer::getBibfilesCache(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. + Buffer const * const pbuf = masterBuffer(); + if (pbuf != this && scope != UpdateChildOnly) return pbuf->getBibfilesCache(); - // We update the cache when first used instead of at loading time. - if (d->bibfiles_cache_.empty()) - const_cast(this)->updateBibfilesCache(scope); + if (!d->bibfile_cache_valid_) + this->updateBibfilesCache(scope); return d->bibfiles_cache_; } @@ -1746,28 +1780,28 @@ support::FileNameList const & Buffer::getBibfilesCache(UpdateScope scope) 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 -{ return d->bibinfo_; } void Buffer::checkBibInfoCache() const { - support::FileNameList const & bibfilesCache = getBibfilesCache(); + // use the master's cache + Buffer const * const tmp = masterBuffer(); + if (tmp != this) { + tmp->checkBibInfoCache(); + return; + } + + // this will also reload the cache if it is invalid + support::FileNameList const & bibfiles_cache = getBibfilesCache(); + // compare the cached timestamps with the actual ones. - support::FileNameList::const_iterator ei = bibfilesCache.begin(); - support::FileNameList::const_iterator en = bibfilesCache.end(); + support::FileNameList::const_iterator ei = bibfiles_cache.begin(); + support::FileNameList::const_iterator en = bibfiles_cache.end(); for (; ei != en; ++ ei) { time_t lastw = ei->lastModified(); time_t prevw = d->bibfile_status_[*ei]; @@ -1776,13 +1810,20 @@ void Buffer::checkBibInfoCache() const d->bibfile_status_[*ei] = lastw; } } - + + // if not valid, then reload the info if (!d->bibinfo_cache_valid_) { d->bibinfo_.clear(); - for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) - it->fillWithBibKeys(d->bibinfo_, it); + fillWithBibKeys(d->bibinfo_); d->bibinfo_cache_valid_ = true; - } + } +} + + +void Buffer::fillWithBibKeys(BiblioInfo & keys) const +{ + for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) + it->fillWithBibKeys(keys, it); } @@ -1983,28 +2024,37 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr) break; case LFUN_BRANCH_ADD: { - docstring const branch_name = func.argument(); + docstring branch_name = func.argument(); if (branch_name.empty()) { dispatched = false; break; } BranchList & branch_list = params().branchlist(); - Branch * branch = branch_list.find(branch_name); - if (branch) { - LYXERR0("Branch " << branch_name << " already exists."); - dr.setError(true); - docstring const msg = - bformat(_("Branch \"%1$s\" already exists."), branch_name); - dr.setMessage(msg); - } else { - branch_list.add(branch_name); - branch = branch_list.find(branch_name); - string const x11hexname = X11hexname(branch->color()); - docstring const str = branch_name + ' ' + from_ascii(x11hexname); - lyx::dispatch(FuncRequest(LFUN_SET_COLOR, str)); - dr.setError(false); - dr.update(Update::Force); + vector const branches = + getVectorFromString(branch_name, branch_list.separator()); + docstring msg; + for (vector::const_iterator it = branches.begin(); + it != branches.end(); ++it) { + branch_name = *it; + Branch * branch = branch_list.find(branch_name); + if (branch) { + LYXERR0("Branch " << branch_name << " already exists."); + dr.setError(true); + if (!msg.empty()) + msg += ("\n"); + msg += bformat(_("Branch \"%1$s\" already exists."), branch_name); + } else { + branch_list.add(branch_name); + branch = branch_list.find(branch_name); + string const x11hexname = X11hexname(branch->color()); + docstring const str = branch_name + ' ' + from_ascii(x11hexname); + lyx::dispatch(FuncRequest(LFUN_SET_COLOR, str)); + dr.setError(false); + dr.update(Update::Force); + } } + if (!msg.empty()) + dr.setMessage(msg); break; } @@ -2028,6 +2078,7 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr) branch->setSelected(func.action() == LFUN_BRANCH_ACTIVATE); dr.setError(false); dr.update(Update::Force); + dr.forceBufferUpdate(); } break; } @@ -2062,8 +2113,10 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr) } } - if (success) + if (success) { dr.update(Update::Force); + dr.forceBufferUpdate(); + } break; } @@ -2189,8 +2242,10 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr) Language const * newL = languages.getLanguage(argument); if (!newL || oldL == newL) break; - if (oldL->rightToLeft() == newL->rightToLeft() && !isMultiLingual()) + if (oldL->rightToLeft() == newL->rightToLeft() && !isMultiLingual()) { changeLanguage(oldL, newL); + dr.forceBufferUpdate(); + } break; } @@ -2346,6 +2401,7 @@ void Buffer::markClean() const // if the .lyx file has been saved, we don't need an // autosave d->bak_clean = true; + d->undo_.markDirty(); } @@ -2703,6 +2759,14 @@ void Buffer::Impl::updateMacros(DocIterator & it, DocIterator & scope) continue; } + if (doing_export && iit->inset->asInsetMath()) { + InsetMath * im = static_cast(iit->inset); + if (im->asHullInset()) { + InsetMathHull * hull = static_cast(im); + hull->recordLocation(it); + } + } + if (iit->inset->lyxCode() != MATHMACRO_CODE) continue; @@ -3234,10 +3298,41 @@ string Buffer::getDefaultOutputFormat() const } +namespace { + // helper class, to guarantee this gets reset properly + class MarkAsExporting { + public: + MarkAsExporting(Buffer const * buf) : buf_(buf) + { + LASSERT(buf_, /* */); + buf_->setExportStatus(true); + } + ~MarkAsExporting() + { + buf_->setExportStatus(false); + } + private: + Buffer const * const buf_; + }; +} + + +void Buffer::setExportStatus(bool e) const +{ + d->doing_export = e; +} + + +bool Buffer::isExporting() const +{ + return d->doing_export; +} + bool Buffer::doExport(string const & format, bool put_in_tempdir, bool includeall, string & result_file) const { + MarkAsExporting exporting(this); string backend_format; OutputParams runparams(¶ms().encoding()); runparams.flavor = OutputParams::LATEX; @@ -3434,6 +3529,7 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir, bool Buffer::preview(string const & format, bool includeall) const { + MarkAsExporting exporting(this); string result_file; // (1) export with all included children (omit \includeonly) if (includeall && !doExport(format, true, true)) @@ -3628,7 +3724,7 @@ void Buffer::updateBuffer(UpdateScope scope, UpdateType utype) const DocumentClass const & textclass = master->params().documentClass(); // do this only if we are the top-level Buffer - if (scope != UpdateMaster || master == this) + if (master == this) checkBibInfoCache(); // keep the buffers to be children in this set. If the call from the @@ -3937,7 +4033,9 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to, if (from == end) break; to = from; - if (from.paragraph().spellCheck(from.pos(), to.pos(), wl, suggestions)) { + from.paragraph().spellCheck(); + SpellChecker::Result res = from.paragraph().spellCheck(from.pos(), to.pos(), wl, suggestions); + if (SpellChecker::misspelled(res)) { word_lang = wl; break; }