]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.cpp
do what the FIXME suggested
[lyx.git] / src / Buffer.cpp
index da23889c5d167fe921d1393625b08c27e93439d0..dc7343677e47deeea18f4594bc7cf6c861593f11 100644 (file)
@@ -14,6 +14,7 @@
 #include "Buffer.h"
 
 #include "Author.h"
+#include "BaseClassList.h"
 #include "BiblioInfo.h"
 #include "BranchList.h"
 #include "buffer_funcs.h"
 #include "sgml.h"
 #include "TexRow.h"
 #include "TexStream.h"
-#include "TextClassList.h"
 #include "Text.h"
+#include "TextClass.h"
 #include "TocBackend.h"
 #include "Undo.h"
 #include "VCBackend.h"
 #include "version.h"
+#include "WordList.h"
 
 #include "insets/InsetBibitem.h"
 #include "insets/InsetBibtex.h"
@@ -79,7 +81,6 @@
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/ExceptionMessage.h"
-#include "support/FileFilterList.h"
 #include "support/FileName.h"
 #include "support/FileNameList.h"
 #include "support/filetools.h"
 #include <boost/shared_ptr.hpp>
 
 #include <algorithm>
+#include <fstream>
 #include <iomanip>
-#include <stack>
+#include <map>
 #include <sstream>
-#include <fstream>
+#include <stack>
+#include <vector>
 
 using namespace std;
 using namespace lyx::support;
@@ -114,12 +117,12 @@ namespace os = support::os;
 
 namespace {
 
-int const LYX_FORMAT = 314; // Uwe Stöhr: scrlttr2 for serial letters
-
-} // namespace anon
-
+int const LYX_FORMAT = 317; // Uwe Stöhr: float placement support for wrap floats
 
 typedef map<string, bool> DepClean;
+typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
+
+} // namespace anon
 
 class Buffer::Impl
 {
@@ -164,9 +167,6 @@ public:
         */
        bool file_fully_loaded;
 
-       /// our Text that should be wrapped in an InsetText
-       InsetText inset;
-
        ///
        mutable TocBackend toc_backend;
 
@@ -204,6 +204,11 @@ public:
        /// A cache for the bibfiles (including bibfiles of loaded child
        /// documents), needed for appropriate update of natbib labels.
        mutable EmbeddedFileList bibfilesCache_;
+
+       mutable RefCache ref_cache_;
+
+       /// our Text that should be wrapped in an InsetText
+       InsetText inset;
 };
 
 /// Creates the per buffer temporary directory
@@ -228,12 +233,11 @@ 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),
-         inset(params), toc_backend(&parent), macro_lock(false),
+         toc_backend(&parent), macro_lock(false),
          embedded_files(), timestamp_(0), checksum_(0), wa_(0), 
          undo_(parent)
 {
        temppath = createBufferTmpDir();
-       inset.setAutoBreakRows(true);
        lyxvc.setBuffer(&parent);
        if (use_gui)
                wa_ = new frontend::WorkAreaManager;
@@ -245,6 +249,9 @@ Buffer::Buffer(string const & file, bool readonly)
 {
        LYXERR(Debug::INFO, "Buffer::Buffer()");
 
+       d->inset.setBuffer(*this);
+       d->inset.initParagraphs(*this);
+       d->inset.setAutoBreakRows(true);
        d->inset.getText(0)->setMacrocontextPosition(par_iterator_begin());
 }
 
@@ -467,6 +474,7 @@ int Buffer::readHeader(Lexer & lex)
        params().headheight.erase();
        params().headsep.erase();
        params().footskip.erase();
+       params().columnsep.erase();
        params().listings_params.clear();
        params().clearLayoutModules();
        params().pdfoptions().clear();
@@ -520,7 +528,7 @@ int Buffer::readHeader(Lexer & lex)
                        s, -1, 0, 0));
        }
        
-       params().makeTextClass();
+       params().makeDocumentClass();
 
        return unknown_tokens;
 }
@@ -568,10 +576,7 @@ bool Buffer::readDocument(Lexer & lex)
        }
 
        // read main text
-       bool const res = text().read(*this, lex, errorList);
-       for_each(text().paragraphs().begin(),
-                text().paragraphs().end(),
-                bind(&Paragraph::setInsetOwner, _1, &inset()));
+       bool const res = text().read(*this, lex, errorList, &(d->inset));
 
        updateMacros();
        updateMacroInstances();
@@ -1187,19 +1192,19 @@ void Buffer::writeLaTeXSource(odocstream & os,
 
 bool Buffer::isLatex() const
 {
-       return params().getTextClass().outputType() == LATEX;
+       return params().documentClass().outputType() == LATEX;
 }
 
 
 bool Buffer::isLiterate() const
 {
-       return params().getTextClass().outputType() == LITERATE;
+       return params().documentClass().outputType() == LITERATE;
 }
 
 
 bool Buffer::isDocBook() const
 {
-       return params().getTextClass().outputType() == DOCBOOK;
+       return params().documentClass().outputType() == DOCBOOK;
 }
 
 
@@ -1230,7 +1235,7 @@ void Buffer::writeDocBookSource(odocstream & os, string const & fname,
 
        d->texrow.reset();
 
-       TextClass const & tclass = params().getTextClass();
+       DocumentClass const & tclass = params().documentClass();
        string const top_element = tclass.latexname();
 
        if (!only_body) {
@@ -1285,7 +1290,7 @@ void Buffer::writeDocBookSource(odocstream & os, string const & fname,
            << " file was created by LyX " << lyx_version
            << "\n  See http://www.lyx.org/ for more information -->\n";
 
-       params().getTextClass().counters().reset();
+       params().documentClass().counters().reset();
 
        loadChildDocuments();
 
@@ -1369,7 +1374,7 @@ void Buffer::getLabelList(vector<docstring> & list) const
        loadChildDocuments();
 
        for (InsetIterator it = inset_iterator_begin(inset()); it; ++it)
-               it.nextInset()->getLabelList(*this, list);
+               it.nextInset()->getLabelList(list);
 }
 
 
@@ -1389,14 +1394,14 @@ void Buffer::updateBibfilesCache() const
                if (it->lyxCode() == BIBTEX_CODE) {
                        InsetBibtex const & inset =
                                static_cast<InsetBibtex const &>(*it);
-                       EmbeddedFileList const bibfiles = inset.getFiles(*this);
+                       EmbeddedFileList const bibfiles = inset.embeddedFiles();
                        d->bibfilesCache_.insert(d->bibfilesCache_.end(),
                                bibfiles.begin(),
                                bibfiles.end());
                } else if (it->lyxCode() == INCLUDE_CODE) {
                        InsetInclude & inset =
                                static_cast<InsetInclude &>(*it);
-                       inset.updateBibfilesCache(*this);
+                       inset.updateBibfilesCache();
                        EmbeddedFileList const & bibfiles =
                                        inset.getBibfilesCache(*this);
                        d->bibfilesCache_.insert(d->bibfilesCache_.end(),
@@ -1486,60 +1491,37 @@ bool Buffer::isMultiLingual() const
 }
 
 
-ParConstIterator Buffer::getParFromID(int const id) const
+DocIterator Buffer::getParFromID(int const id) const
 {
-       ParConstIterator it = par_iterator_begin();
-       ParConstIterator const end = par_iterator_end();
-
-       if (id < 0) {
-               // John says this is called with id == -1 from undo
-               lyxerr << "getParFromID(), id: " << id << endl;
-               return end;
-       }
-
-       for (; it != end; ++it)
-               if (it->id() == id)
-                       return it;
-
-       return end;
-}
-
-
-ParIterator Buffer::getParFromID(int const id)
-{
-       ParIterator it = par_iterator_begin();
-       ParIterator const end = par_iterator_end();
-
        if (id < 0) {
                // John says this is called with id == -1 from undo
                lyxerr << "getParFromID(), id: " << id << endl;
-               return end;
+               return doc_iterator_end(inset());
        }
 
-       for (; it != end; ++it)
-               if (it->id() == id)
+       for (DocIterator it = doc_iterator_begin(inset()); !it.atEnd(); it.forwardPar())
+               if (it.paragraph().id() == id)
                        return it;
 
-       return end;
+       return doc_iterator_end(inset());
 }
 
 
 bool Buffer::hasParWithID(int const id) const
 {
-       ParConstIterator const it = getParFromID(id);
-       return it != par_iterator_end();
+       return !getParFromID(id).atEnd();
 }
 
 
 ParIterator Buffer::par_iterator_begin()
 {
-       return lyx::par_iterator_begin(inset());
+       return ParIterator(doc_iterator_begin(inset()));
 }
 
 
 ParIterator Buffer::par_iterator_end()
 {
-       return lyx::par_iterator_end(inset());
+       return ParIterator(doc_iterator_end(inset()));
 }
 
 
@@ -1876,11 +1858,11 @@ void Buffer::updateEnvironmentMacros(DocIterator & it,
                                // Inset needs its own scope?
                                InsetText const * itext 
                                = iit->inset->asInsetText();
-                               bool newScope = itext->isMacroScope(*this);
+                               bool newScope = itext->isMacroScope();
 
-                               // scope which ends just behind die inset       
+                               // scope which ends just behind the inset       
                                DocIterator insetScope = it;
-                               insetScope.pos()++;
+                               ++insetScope.pos();
 
                                // collect macros in inset
                                it.push_back(CursorSlice(*iit->inset));
@@ -1901,7 +1883,7 @@ void Buffer::updateEnvironmentMacros(DocIterator & it,
                                if (!child)
                                        continue;                               
 
-                               // register it, but only when it is
+                               // register its position, but only when it is
                                // included first in the buffer
                                if (d->children_positions.find(child)
                                    == d->children_positions.end())
@@ -2011,8 +1993,8 @@ void Buffer::updateMacroInstances() const
 {
        LYXERR(Debug::MACROS, "updateMacroInstances for "
                << d->filename.onlyFileName());
-       ParConstIterator it = par_iterator_begin();
-       ParConstIterator end = par_iterator_end();
+       DocIterator it = doc_iterator_begin(inset());
+       DocIterator end = doc_iterator_end(inset());
        for (; it != end; it.forwardPos()) {
                // look for MathData cells in InsetMathNest insets
                Inset * inset = it.nextInset();
@@ -2087,6 +2069,47 @@ void Buffer::writeParentMacros(odocstream & os) const
 }
 
 
+Buffer::References & Buffer::references(docstring const & label)
+{
+       if (d->parent_buffer)
+               return const_cast<Buffer *>(masterBuffer())->references(label);
+
+       RefCache::iterator it = d->ref_cache_.find(label);
+       if (it != d->ref_cache_.end())
+               return it->second.second;
+
+       static InsetLabel const * dummy_il = 0;
+       static References const dummy_refs;
+       it = d->ref_cache_.insert(make_pair(label, make_pair(dummy_il, dummy_refs))).first;
+       return it->second.second;
+}
+
+
+Buffer::References const & Buffer::references(docstring const & label) const
+{
+       return const_cast<Buffer *>(this)->references(label);
+}
+
+
+void Buffer::setInsetLabel(docstring const & label, InsetLabel const * il)
+{
+       masterBuffer()->d->ref_cache_[label].first = il;
+}
+
+
+InsetLabel const * Buffer::insetLabel(docstring const & label) const
+{
+       return masterBuffer()->d->ref_cache_[label].first;
+}
+
+
+void Buffer::clearReferenceCache() const
+{
+       if (!d->parent_buffer)
+               d->ref_cache_.clear();
+}
+
+
 void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to,
        InsetCode code)
 {
@@ -2338,6 +2361,9 @@ void Buffer::autoSave() const
 
 void Buffer::resetChildDocuments(bool close_them) const
 {
+       if (text().empty())
+               return;
+
        for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
                if (it->lyxCode() != INCLUDE_CODE)
                        continue;
@@ -2347,9 +2373,6 @@ void Buffer::resetChildDocuments(bool close_them) const
                resetParentBuffer(this, ip, close_them);
        }
 
-       if (use_gui && masterBuffer() == this)
-               updateLabels(*this);
-
        // clear references to children in macro tables
        d->children_positions.clear();
        d->position_to_children.clear();
@@ -2372,9 +2395,6 @@ void Buffer::loadChildDocuments() const
                child->loadChildDocuments();
        }
 
-       if (use_gui && masterBuffer() == this)
-               updateLabels(*this);
-
        updateMacros();
 }
 
@@ -2556,7 +2576,7 @@ vector<Format const *> Buffer::exportableFormats(bool only_viewable) const
 vector<string> Buffer::backends() const
 {
        vector<string> v;
-       if (params().getTextClass().isTeXClassAvailable()) {
+       if (params().baseClass()->isTeXClassAvailable()) {
                v.push_back(bufferFormat());
                // FIXME: Don't hardcode format names here, but use a flag
                if (v.back() == "latex")