]> git.lyx.org Git - lyx.git/blobdiff - src/buffer.C
move some selection related stuff over to textcursor.C
[lyx.git] / src / buffer.C
index ccb271815e175d2b3616dc2cbc637f0919e6b0ec..658cc859c46c22d4c999a79b182cdb9a1ebbed2f 100644 (file)
@@ -11,6 +11,7 @@
 #include <config.h>
 
 #include "buffer.h"
+#include "buffer_funcs.h"
 #include "bufferlist.h"
 #include "LyXAction.h"
 #include "lyxrc.h"
@@ -45,7 +46,6 @@
 #include "mathed/formulamacro.h"
 #include "mathed/formula.h"
 
-#include "insets/inseterror.h"
 #include "insets/insetbibitem.h"
 #include "insets/insetbibtex.h"
 #include "insets/insetinclude.h"
@@ -113,7 +113,7 @@ extern BufferList bufferlist;
 
 namespace {
 
-const int LYX_FORMAT = 223;
+const int LYX_FORMAT = 224;
 
 } // namespace anon
 
@@ -148,7 +148,7 @@ Buffer::~Buffer()
                users->buffer(0);
 
        if (!tmppath.empty() && destroyDir(tmppath) != 0) {
-               Alert::warning(_("Could not remove temporary directory"), 
+               Alert::warning(_("Could not remove temporary directory"),
                        bformat(_("Could not remove the temporary directory %1$s"), tmppath));
        }
 
@@ -206,7 +206,8 @@ void Buffer::setReadonly(bool flag)
        if (read_only != flag) {
                read_only = flag;
                updateTitles();
-               users->owner()->getDialogs().updateBufferDependent(false);
+               if (users)
+                       users->owner()->getDialogs().updateBufferDependent(false);
        }
 }
 
@@ -249,7 +250,7 @@ namespace {
 
 void unknownClass(string const & unknown)
 {
-       Alert::warning(_("Unknown document class"), 
+       Alert::warning(_("Unknown document class"),
                bformat(_("Using the default document class, because the "
                        " class %1$s is unknown."), unknown));
 }
@@ -273,12 +274,19 @@ int Buffer::readHeader(LyXLex & lex)
                lyxerr[Debug::PARSER] << "Handling header token: `"
                                      << token << '\'' << endl;
 
+
                string unknown = params.readToken(lex, token);
                if (!unknown.empty()) {
                        if (unknown[0] != '\\') {
                                unknownClass(unknown);
                        } else {
                                ++unknown_tokens;
+                               string const s = bformat(_("Unknown token: "
+                                                          "%1$s %2$s\n"), 
+                                                        token, 
+                                                        lex.getString());
+                               parseError(ErrorItem(_("Header error"), s, 
+                                                    -1, 0, 0));
                        }
                }
        }
@@ -296,14 +304,11 @@ int Buffer::readHeader(LyXLex & lex)
 // Returns false if "\the_end" is not read (Asger)
 bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
 {
-       int unknown_tokens = 0;
-
        Paragraph::depth_type depth = 0;
        bool the_end_read = false;
 
        if (paragraphs.empty()) {
-               unknown_tokens += readHeader(lex);
-
+               readHeader(lex);
                if (!params.getLyXTextClass().load()) {
                        string theclass = params.getLyXTextClass().name();
                        Alert::error(_("Can't load document class"), bformat(
@@ -338,20 +343,7 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
                        continue;
                }
 
-               unknown_tokens += readParagraph(lex, token, paragraphs, pit, depth);
-       }
-
-
-       if (unknown_tokens > 0) {
-               string s;
-               if (unknown_tokens == 1) {
-                       s = bformat(_("Encountered one unknown token when reading "
-                               "the document %1$s."), fileName());
-               } else {
-                       s = bformat(_("Encountered %1$s unknown tokens when reading "
-                               "the document %2$s."), tostr(unknown_tokens), fileName());
-               }
-               Alert::warning(_("Document format failure"), s);
+               readParagraph(lex, token, paragraphs, pit, depth);
        }
 
        return the_end_read;
@@ -359,8 +351,8 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
 
 
 int Buffer::readParagraph(LyXLex & lex, string const & token,
-                     ParagraphList & pars, ParagraphList::iterator & pit,
-                     Paragraph::depth_type & depth)
+                         ParagraphList & pars, ParagraphList::iterator & pit,
+                         Paragraph::depth_type & depth)
 {
        static Change current_change;
        int unknown = 0;
@@ -368,21 +360,23 @@ int Buffer::readParagraph(LyXLex & lex, string const & token,
        if (token == "\\layout") {
                lex.pushToken(token);
 
-               Paragraph * par = new Paragraph();
-               par->params().depth(depth);
+               Paragraph par;
+               par.params().depth(depth);
                if (params.tracking_changes)
-                       par->trackChanges();
+                       par.trackChanges();
                LyXFont f(LyXFont::ALL_INHERIT, params.language);
-               par->setFont(0, f);
-
-               // FIXME: goddamn InsetTabular makes us pass a Buffer
-               // not BufferParams
-               unknown += ::readParagraph(*this, *par, lex);
+               par.setFont(0, f);
 
                // insert after
                if (pit != pars.end())
                        ++pit;
+
                pit = pars.insert(pit, par);
+
+               // FIXME: goddamn InsetTabular makes us pass a Buffer
+               // not BufferParams
+               ::readParagraph(*this, *pit, lex);
+
        } else if (token == "\\begin_deeper") {
                ++depth;
        } else if (token == "\\end_deeper") {
@@ -414,7 +408,7 @@ void Buffer::insertStringAsLines(ParagraphList::iterator & par, pos_type & pos,
        for(string::const_iterator cit = str.begin();
            cit != str.end(); ++cit) {
                if (*cit == '\n') {
-                       if (autobreakrows && (!par->empty() || layout->keepempty)) {
+                       if (autobreakrows && (!par->empty() || par->allowEmpty())) {
                                breakParagraph(params, paragraphs, par, pos,
                                               layout->isEnvironment());
                                ++par;
@@ -425,12 +419,10 @@ void Buffer::insertStringAsLines(ParagraphList::iterator & par, pos_type & pos,
                        }
                        // do not insert consecutive spaces if !free_spacing
                } else if ((*cit == ' ' || *cit == '\t') &&
-                          space_inserted && !layout->free_spacing &&
-                                  !par->isFreeSpacing())
-               {
+                          space_inserted && !par->isFreeSpacing()) {
                        continue;
                } else if (*cit == '\t') {
-                       if (!layout->free_spacing && !par->isFreeSpacing()) {
+                       if (!par->isFreeSpacing()) {
                                // tabs are like spaces here
                                par->insertChar(pos, ' ', font);
                                ++pos;
@@ -680,8 +672,8 @@ bool Buffer::writeFile(string const & fname) const
 
        // this will write out all the paragraphs
        // using recursive descent.
-       ParagraphList::iterator pit = paragraphs.begin();
-       ParagraphList::iterator pend = paragraphs.end();
+       ParagraphList::const_iterator pit = paragraphs.begin();
+       ParagraphList::const_iterator pend = paragraphs.end();
        for (; pit != pend; ++pit)
                pit->write(this, ofs, params, depth);
 
@@ -733,27 +725,10 @@ string const Buffer::asciiParagraph(Paragraph const & par,
                                    bool noparbreak) const
 {
        ostringstream buffer;
-       Paragraph::depth_type depth = 0;
        int ltype = 0;
        Paragraph::depth_type ltype_depth = 0;
        bool ref_printed = false;
-//     if (!par->previous()) {
-#if 0
-       // begins or ends a deeper area ?
-       if (depth != par->params().depth()) {
-               if (par->params().depth() > depth) {
-                       while (par->params().depth() > depth) {
-                               ++depth;
-                       }
-               } else {
-                       while (par->params().depth() < depth) {
-                               --depth;
-                       }
-               }
-       }
-#else
-       depth = par.params().depth();
-#endif
+       Paragraph::depth_type depth = par.params().depth();
 
        // First write the layout
        string const & tmp = par.layout()->name();
@@ -951,7 +926,8 @@ void Buffer::writeFileAscii(ostream & os, int linelen)
 
 void Buffer::makeLaTeXFile(string const & fname,
                           string const & original_path,
-                          bool nice, bool only_body, bool only_preamble)
+                          LatexRunParams const & runparams,
+                          bool only_body, bool only_preamble)
 {
        lyxerr[Debug::LATEX] << "makeLaTeXFile..." << endl;
 
@@ -964,7 +940,8 @@ void Buffer::makeLaTeXFile(string const & fname,
                return;
        }
 
-       makeLaTeXFile(ofs, original_path, nice, only_body, only_preamble);
+       makeLaTeXFile(ofs, original_path,
+                     runparams, only_body, only_preamble);
 
        ofs.close();
        if (ofs.fail()) {
@@ -975,9 +952,11 @@ void Buffer::makeLaTeXFile(string const & fname,
 
 void Buffer::makeLaTeXFile(ostream & os,
                           string const & original_path,
-                          bool nice, bool only_body, bool only_preamble)
+                          LatexRunParams const & runparams_in,
+                          bool only_body, bool only_preamble)
 {
-       niceFile = nice; // this will be used by Insetincludes.
+       LatexRunParams runparams = runparams_in;
+       niceFile = runparams.nice; // this will be used by Insetincludes.
 
        // validate the buffer.
        lyxerr[Debug::LATEX] << "  Validating buffer..." << endl;
@@ -990,7 +969,7 @@ void Buffer::makeLaTeXFile(ostream & os,
        // first paragraph of the document. (Asger)
        texrow.start(paragraphs.begin()->id(), 0);
 
-       if (!only_body && nice) {
+       if (!only_body && runparams.nice) {
                os << "%% " << lyx_docversion << " created this file.  "
                        "For more info, see http://www.lyx.org/.\n"
                        "%% Do not edit unless you really know what "
@@ -1007,7 +986,7 @@ void Buffer::makeLaTeXFile(ostream & os,
        // original_path is set. This is done for usual tex-file, but not
        // for nice-latex-file. (Matthias 250696)
        if (!only_body) {
-               if (!nice) {
+               if (!runparams.nice) {
                        // code for usual, NOT nice-latex-file
                        os << "\\batchmode\n"; // changed
                        // from \nonstopmode
@@ -1026,7 +1005,7 @@ void Buffer::makeLaTeXFile(ostream & os,
                }
 
                // Write the preamble
-               params.writeLaTeX(os, features, texrow);
+               runparams.use_babel = params.writeLaTeX(os, features, texrow);
 
                if (only_preamble)
                        return;
@@ -1044,7 +1023,7 @@ void Buffer::makeLaTeXFile(ostream & os,
                texrow.newline();
        }
 
-       latexParagraphs(this, paragraphs, os, texrow, false);
+       latexParagraphs(this, paragraphs, os, texrow, runparams);
 
        // add this just in case after all the paragraphs
        os << endl;
@@ -1168,8 +1147,6 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
        string item_name;
        vector<string> environment_stack(5);
 
-       users->resetErrorList();
-
        ParagraphList::iterator pit = paragraphs.begin();
        ParagraphList::iterator pend = paragraphs.end();
        for (; pit != pend; ++pit) {
@@ -1208,8 +1185,7 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
 
                case LATEX_COMMAND:
                        if (depth != 0)
-                               sgmlError(pit, 0,
-                                         _("Error: Wrong depth for LatexType Command.\n"));
+                               parseError(ErrorItem(_("Error:"), _("Wrong depth for LatexType Command.\n"), pit->id(), 0, pit->size()));
 
                        if (!environment_stack[depth].empty()) {
                                sgml::closeTag(ofs, depth, false, environment_stack[depth]);
@@ -1299,8 +1275,6 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
 
        // we want this to be true outside previews (for insetexternal)
        niceFile = true;
-
-       users->showErrorList(_("LinuxDoc"));
 }
 
 
@@ -1518,7 +1492,7 @@ void Buffer::simpleLinuxDocOnePar(ostream & os,
                        bool ws;
                        string str;
                        boost::tie(ws, str) = sgml::escapeChar(c);
-                       if (ws && !style->free_spacing && !par->isFreeSpacing()) {
+                       if (ws && !par->isFreeSpacing()) {
                                // in freespacing mode, spaces are
                                // non-breaking characters
                                if (desc_on) {// if char is ' ' then...
@@ -1553,14 +1527,6 @@ void Buffer::simpleLinuxDocOnePar(ostream & os,
 }
 
 
-// Print an error message.
-void Buffer::sgmlError(ParagraphList::iterator pit, int pos,
-                      string const & message) const
-{
-       users->addError(ErrorItem(message, string(), pit->id(), pos, pos));
-}
-
-
 void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
 {
        ofstream ofs(fname.c_str());
@@ -1625,8 +1591,6 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
        string item_name;
        string command_name;
 
-       users->resetErrorList();
-
        ParagraphList::iterator par = paragraphs.begin();
        ParagraphList::iterator pend = paragraphs.end();
 
@@ -1640,7 +1604,7 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
 
                // environment tag closing
                for (; depth > par->params().depth(); --depth) {
-                       if (environment_inner[depth] != "!-- --") {
+                       if (environment_inner[depth] != "!-- --" && !environment_inner[depth].empty()) {
                                item_name = "listitem";
                                sgml::closeTag(ofs, command_depth + depth, false, item_name);
                                if (environment_inner[depth] == "varlistentry")
@@ -1676,8 +1640,7 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
 
                case LATEX_COMMAND:
                        if (depth != 0)
-                               sgmlError(par, 0,
-                                         _("Error: Wrong depth for LatexType Command.\n"));
+                               parseError(ErrorItem(_("Error"), _("Wrong depth for LatexType Command."), par->id(), 0, par->size()));
 
                        command_name = style->latexname();
 
@@ -1843,7 +1806,6 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
 
        // we want this to be true outside previews (for insetexternal)
        niceFile = true;
-       users->showErrorList(_("DocBook"));
 }
 
 
@@ -1903,9 +1865,9 @@ void Buffer::simpleDocBookOnePar(ostream & os,
 
                        if (style->pass_thru) {
                                os << c;
-                       } else if (style->free_spacing || par->isFreeSpacing() || c != ' ') {
+                       } else if (par->isFreeSpacing() || c != ' ') {
                                        os << str;
-                       } else if (desc_on ==1) {
+                       } else if (desc_on == 1) {
                                ++char_line_count;
                                os << "\n</term><listitem><para>";
                                desc_on = 2;
@@ -1954,11 +1916,11 @@ int Buffer::runChktex()
        Path p(path); // path to LaTeX file
        users->owner()->message(_("Running chktex..."));
 
-       // Remove all error insets
-       bool const removedErrorInsets = users->removeAutoInsets();
-
        // Generate the LaTeX file if neccessary
-       makeLaTeXFile(name, org_path, false);
+       LatexRunParams runparams;
+       runparams.flavor = LatexRunParams::LATEX;
+       runparams.nice = false;
+       makeLaTeXFile(name, org_path, runparams);
 
        TeXErrors terr;
        Chktex chktex(lyxrc.chktex_command, name, filePath());
@@ -1966,21 +1928,12 @@ int Buffer::runChktex()
 
        if (res == -1) {
                Alert::error(_("chktex failure"),
-                       _("Could not run chktex successfully."));
+                            _("Could not run chktex successfully."));
        } else if (res > 0) {
                // Insert all errors as errors boxes
-               ErrorList el (*this, terr); 
-               users->setErrorList(el);
-               users->showErrorList(_("ChkTeX"));
+               parseErrors(*this, terr);
        }
 
-       // if we removed error insets before we ran chktex or if we inserted
-       // error insets after we ran chktex, this must be run:
-       if (removedErrorInsets || res) {
-#warning repaint needed here, or do you mean update() ?
-               users->repaint();
-               users->fitCursor();
-       }
        users->owner()->busy(false);
 
        return res;
@@ -2034,24 +1987,23 @@ void Buffer::validate(LaTeXFeatures & features) const
 }
 
 
-vector<string> const Buffer::getLabelList() const
+void Buffer::getLabelList(std::vector<string> & list) const
 {
        /// if this is a child document and the parent is already loaded
        /// Use the parent's list instead  [ale990407]
        if (!params.parentname.empty()
            && bufferlist.exists(params.parentname)) {
                Buffer const * tmp = bufferlist.getBuffer(params.parentname);
-               if (tmp)
-                       return tmp->getLabelList();
+               if (tmp) {
+                       tmp->getLabelList(list);
+                       return;
+               }
        }
 
-       vector<string> label_list;
        for (inset_iterator it = inset_const_iterator_begin();
             it != inset_const_iterator_end(); ++it) {
-               vector<string> const l = it->getLabelList();
-               label_list.insert(label_list.end(), l.begin(), l.end());
+               it->getLabelList(list);
        }
-       return label_list;
 }
 
 
@@ -2156,7 +2108,7 @@ void Buffer::changeLanguage(Language const * from, Language const * to)
 
        ParIterator end = par_iterator_end();
        for (ParIterator it = par_iterator_begin(); it != end; ++it)
-               (*it)->changeLanguage(params, from, to);
+               it->changeLanguage(params, from, to);
 }
 
 
@@ -2170,7 +2122,7 @@ bool Buffer::isMultiLingual()
 {
        ParIterator end = par_iterator_end();
        for (ParIterator it = par_iterator_begin(); it != end; ++it)
-               if ((*it)->isMultiLingual(params))
+               if (it->isMultiLingual(params))
                        return true;
 
        return false;
@@ -2203,35 +2155,31 @@ Inset * Buffer::getInsetFromID(int id_arg) const
 }
 
 
-ParagraphList::iterator Buffer::getParFromID(int id) const
+ParIterator Buffer::getParFromID(int id) const
 {
 #warning FIXME: const correctness! (Andre)
-       ParIterator it(const_cast<Buffer*>(this)->par_iterator_begin());
-       ParIterator end(const_cast<Buffer*>(this)->par_iterator_end());
+       ParIterator it = const_cast<Buffer*>(this)->par_iterator_begin();
+       ParIterator end = const_cast<Buffer*>(this)->par_iterator_end();
 
 #warning FIXME, perhaps this func should return a ParIterator? (Lgb)
        if (id < 0) {
                // John says this is called with id == -1 from undo
                lyxerr << "getParFromID(), id: " << id << endl;
-               return 0;
+               return end;
        }
 
-       for (; it != end; ++it) {
-               // go on then, show me how to remove
-               // the cast
-               if ((*it)->id() == id) {
-                       return *it;
-               }
-       }
+       for (; it != end; ++it)
+               if (it->id() == id)
+                       return it;
 
-       return 0;
+       return end;
 }
 
 
 bool Buffer::hasParWithID(int id) const
 {
-       ParIterator it(const_cast<Buffer*>(this)->par_iterator_begin());
-       ParIterator end(const_cast<Buffer*>(this)->par_iterator_end());
+       ParConstIterator it = par_iterator_begin();
+       ParConstIterator end = par_iterator_end();
 
        if (id < 0) {
                // John says this is called with id == -1 from undo
@@ -2240,7 +2188,7 @@ bool Buffer::hasParWithID(int id) const
        }
 
        for (; it != end; ++it)
-               if ((*it)->id() == id)
+               if (it->id() == id)
                        return true;
 
        return false;
@@ -2249,24 +2197,24 @@ bool Buffer::hasParWithID(int id) const
 
 ParIterator Buffer::par_iterator_begin()
 {
-       return ParIterator(&*(paragraphs.begin()));
+       return ParIterator(paragraphs.begin(), paragraphs);
 }
 
 
 ParIterator Buffer::par_iterator_end()
 {
-       return ParIterator();
+       return ParIterator(paragraphs.end(), paragraphs);
 }
 
 ParConstIterator Buffer::par_iterator_begin() const
 {
-       return ParConstIterator(&*(paragraphs.begin()));
+       return ParConstIterator(const_cast<ParagraphList&>(paragraphs).begin(), paragraphs);
 }
 
 
 ParConstIterator Buffer::par_iterator_end() const
 {
-       return ParConstIterator();
+       return ParConstIterator(const_cast<ParagraphList&>(paragraphs).end(), paragraphs);
 }
 
 
@@ -2389,7 +2337,7 @@ void Buffer::setParentName(string const & name)
 
 
 Buffer::inset_iterator::inset_iterator()
-       : pit(0), pend(0)
+       : pit(), pend()
 {}
 
 
@@ -2400,6 +2348,32 @@ Buffer::inset_iterator::inset_iterator(base_type p, base_type e)
 }
 
 
+Buffer::inset_iterator Buffer::inset_iterator_begin()
+{
+       return inset_iterator(paragraphs.begin(), paragraphs.end());
+}
+
+
+Buffer::inset_iterator Buffer::inset_iterator_end()
+{
+       return inset_iterator(paragraphs.end(), paragraphs.end());
+}
+
+
+Buffer::inset_iterator Buffer::inset_const_iterator_begin() const
+{
+       return inset_iterator(const_cast<ParagraphList&>(paragraphs).begin(),
+                             const_cast<ParagraphList&>(paragraphs).end());
+}
+
+
+Buffer::inset_iterator Buffer::inset_const_iterator_end() const
+{
+       return inset_iterator(const_cast<ParagraphList&>(paragraphs).end(),
+                             const_cast<ParagraphList&>(paragraphs).end());
+}
+
+
 Buffer::inset_iterator & Buffer::inset_iterator::operator++()
 {
        if (pit != pend) {
@@ -2423,13 +2397,13 @@ Buffer::inset_iterator Buffer::inset_iterator::operator++(int)
 
 Buffer::inset_iterator::reference Buffer::inset_iterator::operator*()
 {
-       return *it.getInset();
+       return *it->inset;
 }
 
 
 Buffer::inset_iterator::pointer Buffer::inset_iterator::operator->()
 {
-       return it.getInset();
+       return it->inset;
 }
 
 
@@ -2441,7 +2415,7 @@ ParagraphList::iterator Buffer::inset_iterator::getPar() const
 
 lyx::pos_type Buffer::inset_iterator::getPos() const
 {
-       return it.getPos();
+       return it->pos;
 }