]> git.lyx.org Git - lyx.git/blobdiff - src/buffer.C
"Inter-word Space"
[lyx.git] / src / buffer.C
index 78e2e0795f0b846515432970fcbbc20e8597b8ad..2200f0dc84d9835d1c34e356a3d5ff6634ea5bf5 100644 (file)
@@ -1,15 +1,11 @@
-/* This file is part of
- * ======================================================
+/**
+ * \file buffer.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
  *
- *           LyX, The Document Processor
+ * \author Lars Gullik Bjønnes
  *
- *          Copyright 1995 Matthias Ettrich
- *           Copyright 1995-2001 The LyX Team.
- *
- *           This file is Copyright 1996-2001
- *           Lars Gullik Bjønnes
- *
- * ======================================================
+ * Full author contact details are available in file CREDITS
  */
 
 #include <config.h>
@@ -32,6 +28,7 @@
 #include "gettext.h"
 #include "language.h"
 #include "exporter.h"
+#include "errorlist.h"
 #include "Lsstream.h"
 #include "format.h"
 #include "BufferView.h"
@@ -40,6 +37,7 @@
 #include "lyxtextclasslist.h"
 #include "sgml.h"
 #include "paragraph_funcs.h"
+#include "messages.h"
 #include "author.h"
 
 #include "frontends/LyXView.h"
 #include "mathed/formulamacro.h"
 #include "mathed/formula.h"
 
-#include "insets/inset.h"
 #include "insets/inseterror.h"
-#include "insets/insethfill.h"
-#include "insets/insetlabel.h"
-#include "insets/insetref.h"
-#include "insets/inseturl.h"
-#include "insets/insetnote.h"
-#include "insets/insetquotes.h"
-#include "insets/insetlatexaccent.h"
 #include "insets/insetbibitem.h"
 #include "insets/insetbibtex.h"
-#include "insets/insetcite.h"
-#include "insets/insetexternal.h"
-#include "insets/insetindex.h"
 #include "insets/insetinclude.h"
-#include "insets/insettoc.h"
-#include "insets/insetparent.h"
-#include "insets/insetspecialchar.h"
 #include "insets/insettext.h"
-#include "insets/insetert.h"
-#include "insets/insetgraphics.h"
-#include "insets/insetfoot.h"
-#include "insets/insetmarginal.h"
-#include "insets/insetoptarg.h"
-#include "insets/insetminipage.h"
-#include "insets/insetfloat.h"
-#include "insets/insetwrap.h"
-#include "insets/insettabular.h"
-#if 0
-#include "insets/insettheorem.h"
-#include "insets/insetlist.h"
-#endif
-#include "insets/insetcaption.h"
-#include "insets/insetfloatlist.h"
 
 #include "frontends/Dialogs.h"
 #include "frontends/Alert.h"
@@ -91,6 +60,7 @@
 #include "support/filetools.h"
 #include "support/path.h"
 #include "support/os.h"
+#include "support/tostr.h"
 #include "support/lyxlib.h"
 #include "support/FileInfo.h"
 #include "support/lyxmanip.h"
@@ -98,7 +68,6 @@
 
 #include <boost/bind.hpp>
 #include <boost/tuple/tuple.hpp>
-#include "BoostFormat.h"
 
 #include <fstream>
 #include <iomanip>
@@ -144,7 +113,7 @@ extern BufferList bufferlist;
 
 namespace {
 
-const int LYX_FORMAT = 222;
+const int LYX_FORMAT = 223;
 
 } // namespace anon
 
@@ -178,8 +147,9 @@ Buffer::~Buffer()
        if (users)
                users->buffer(0);
 
-       if (!tmppath.empty()) {
-               DestroyBufferTmpDir(tmppath);
+       if (!tmppath.empty() && destroyDir(tmppath) != 0) {
+               Alert::warning(_("Could not remove temporary directory"),
+                       bformat(_("Could not remove the temporary directory %1$s"), tmppath));
        }
 
        paragraphs.clear();
@@ -192,10 +162,7 @@ Buffer::~Buffer()
 string const Buffer::getLatexName(bool no_path) const
 {
        string const name = ChangeExtension(MakeLatexName(fileName()), ".tex");
-       if (no_path)
-               return OnlyFilename(name);
-       else
-               return name;
+       return no_path ? OnlyFilename(name) : name;
 }
 
 
@@ -280,23 +247,11 @@ void Buffer::setFileName(string const & newfile)
 // We'll remove this later. (Lgb)
 namespace {
 
-#ifdef WITH_WARNINGS
-#warning this is never set to != 0 !!! - remove ?
-#endif
-int unknown_layouts;
-
 void unknownClass(string const & unknown)
 {
-       string msg =
-#if USE_BOOST_FORMAT
-               boost::io::str(boost::format(
-                       _("The document uses an unknown textclass \"%1$s\".")) % unknown)
-               + _("-- substituting default.");
-#else
-               _("The document uses an unknown textclass ")
-               + unknown + _("-- substituting default.");
-#endif
-       Alert::alert(_("Textclass error"), msg);
+       Alert::warning(_("Unknown document class"),
+               bformat(_("Using the default document class, because the "
+                       " class %1$s is unknown."), unknown));
 }
 
 } // anon
@@ -323,7 +278,7 @@ int Buffer::readHeader(LyXLex & lex)
                        if (unknown[0] != '\\') {
                                unknownClass(unknown);
                        } else {
-                       ++unknown_tokens;
+                               ++unknown_tokens;
                        }
                }
        }
@@ -341,37 +296,24 @@ int Buffer::readHeader(LyXLex & lex)
 // Returns false if "\the_end" is not read (Asger)
 bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
 {
-       unknown_layouts = 0;
        int unknown_tokens = 0;
 
-       int pos = 0;
        Paragraph::depth_type depth = 0;
        bool the_end_read = false;
 
-       LyXFont font(LyXFont::ALL_INHERIT, params.language);
-
        if (paragraphs.empty()) {
                unknown_tokens += readHeader(lex);
 
                if (!params.getLyXTextClass().load()) {
-#if USE_BOOST_FORMAT
-                       Alert::alert(_("Textclass Loading Error!"),
-                                  boost::io::str(boost::format(_("Can't load textclass %1$s")) %
-                                  params.getLyXTextClass().name()),
-                                  _("-- substituting default."));
-#else
-                       Alert::alert(_("Textclass Loading Error!"),
-                                    _("Can't load textclass ")
-                                    + params.getLyXTextClass().name(),
-                                    _("-- substituting default."));
-#endif
+                       string theclass = params.getLyXTextClass().name();
+                       Alert::error(_("Can't load document class"), bformat(
+                                       "Using the default document class, because the "
+                                       " class %1$s could not be loaded.", theclass));
                        params.textclass = 0;
                }
        } else {
                // We are inserting into an existing document
-               users->text->breakParagraph(users, paragraphs);
-               pos = 0;
-               markDirty();
+               users->text->breakParagraph(paragraphs);
 
                // We don't want to adopt the parameters from the
                // document we insert, so read them into a temporary buffer
@@ -396,391 +338,69 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
                        continue;
                }
 
-               unknown_tokens += readToken(lex, paragraphs, pit, token, pos, depth, font);
+               unknown_tokens += readParagraph(lex, token, paragraphs, pit, depth);
        }
 
-       if (unknown_layouts > 0) {
-               string s = _("Couldn't set the layout for ");
-               if (unknown_layouts == 1) {
-                       s += _("one paragraph");
-               } else {
-                       s += tostr(unknown_layouts);
-                       s += _(" paragraphs");
-               }
-#if USE_BOOST_FORMAT
-               Alert::alert(_("Textclass Loading Error!"), s,
-                          boost::io::str(boost::format(_("When reading %1$s")) % fileName()));
-#else
-               Alert::alert(_("Textclass Loading Error!"), s,
-                            _("When reading ") + fileName());
-#endif
-       }
 
        if (unknown_tokens > 0) {
-               string s = _("Encountered ");
+               string s;
                if (unknown_tokens == 1) {
-                       s += _("one unknown token");
+                       s = bformat(_("Encountered one unknown token when reading "
+                               "the document %1$s."), fileName());
                } else {
-                       s += tostr(unknown_tokens);
-                       s += _(" unknown tokens");
+                       s = bformat(_("Encountered %1$s unknown tokens when reading "
+                               "the document %2$s."), tostr(unknown_tokens), fileName());
                }
-#if USE_BOOST_FORMAT
-               Alert::alert(_("Textclass Loading Error!"), s,
-                          boost::io::str(boost::format(_("When reading %1$s")) % fileName()));
-#else
-               Alert::alert(_("Textclass Loading Error!"), s,
-                            _("When reading ") +  fileName());
-#endif
+               Alert::warning(_("Document format failure"), s);
        }
 
        return the_end_read;
 }
 
 
-int
-Buffer::readToken(LyXLex & lex, ParagraphList & pars,
-                  ParagraphList::iterator & pit,
-                  string const & token, int & pos,
-                  Paragraph::depth_type & depth,
-                  LyXFont & font)
+int Buffer::readParagraph(LyXLex & lex, string const & token,
+                     ParagraphList & pars, ParagraphList::iterator & pit,
+                     Paragraph::depth_type & depth)
 {
        static Change current_change;
        int unknown = 0;
 
-       // The order of the tags tested may seem unnatural, but this
-       // has been done in order to reduce the number of string
-       // comparisons needed to recognize a given token. This leads
-       // on large documents like UserGuide to a reduction of a
-       // factor 5! (JMarc)
-       if (token[0] != '\\') {
-               for (string::const_iterator cit = token.begin();
-                    cit != token.end(); ++cit) {
-                       pit->insertChar(pos, (*cit), font, current_change);
-                       ++pos;
-               }
-       } else if (token == "\\layout") {
-               // reset the font as we start a new layout and if the font is
-               // not ALL_INHERIT,document_language then it will be set to the
-               // right values after this tag (Jug 20020420)
-               font = LyXFont(LyXFont::ALL_INHERIT, params.language);
-
-               lex.eatLine();
-               string layoutname = lex.getString();
-
-               LyXTextClass const & tclass = params.getLyXTextClass();
+       if (token == "\\layout") {
+               lex.pushToken(token);
 
-               if (layoutname.empty()) {
-                       layoutname = tclass.defaultLayoutName();
-               }
-               bool hasLayout = tclass.hasLayout(layoutname);
-               if (!hasLayout) {
-                       lyxerr << "Layout '" << layoutname << "' does not"
-                              << " exist in textclass '" << tclass.name()
-                              << "'." << endl;
-                       lyxerr << "Trying to use default layout instead."
-                              << endl;
-                       layoutname = tclass.defaultLayoutName();
-               }
-
-#ifdef USE_CAPTION
-               // The is the compability reading of layout caption.
-               // It can be removed in LyX version 1.3.0. (Lgb)
-               if (compare_ascii_no_case(layoutname, "caption") == 0) {
-                       // We expect that the par we are now working on is
-                       // really inside a InsetText inside a InsetFloat.
-                       // We also know that captions can only be
-                       // one paragraph. (Lgb)
-
-                       // We should now read until the next "\layout"
-                       // is reached.
-                       // This is probably not good enough, what if the
-                       // caption is the last par in the document (Lgb)
-                       istream & ist = lex.getStream();
-                       stringstream ss;
-                       string line;
-                       int begin = 0;
-                       while (true) {
-                               getline(ist, line);
-                               if (prefixIs(line, "\\layout")) {
-                                       lex.pushToken(line);
-                                       break;
-                               }
-                               if (prefixIs(line, "\\begin_inset"))
-                                       ++begin;
-                               if (prefixIs(line, "\\end_inset")) {
-                                       if (begin)
-                                               --begin;
-                                       else {
-                                               lex.pushToken(line);
-                                               break;
-                                       }
-                               }
+               Paragraph par;
+               par.owningBuffer(*this);
+               par.params().depth(depth);
+               if (params.tracking_changes)
+                       par.trackChanges();
+               LyXFont f(LyXFont::ALL_INHERIT, params.language);
+               par.setFont(0, f);
 
-                               ss << line << '\n';
-                       }
-                       // Now we should have the whole layout in ss
-                       // we should now be able to give this to the
-                       // caption inset.
-                       ss << "\\end_inset\n";
-
-                       // This seems like a bug in stringstream.
-                       // We really should be able to use ss
-                       // directly. (Lgb)
-                       istringstream is(ss.str());
-                       LyXLex tmplex(0, 0);
-                       tmplex.setStream(is);
-                       Inset * inset = new InsetCaption;
-                       inset->Read(this, tmplex);
-                       pit->InsertInset(pos, inset, font);
-                       ++pos;
-               } else {
-#endif
-                       Paragraph * par = new Paragraph();
-                       par->layout(params.getLyXTextClass().defaultLayout());
-                       if (params.tracking_changes)
-                               par->trackChanges();
-                       pos = 0;
-                       par->layout(params.getLyXTextClass()[layoutname]);
-                       // Test whether the layout is obsolete.
-                       LyXLayout_ptr const & layout = par->layout();
-                       if (!layout->obsoleted_by().empty())
-                               par->layout(params.getLyXTextClass()[layout->obsoleted_by()]);
-                       par->params().depth(depth);
-                       // insert after
-                       if (pit != pars.end())
-                               ++pit;
-                       pit = pars.insert(pit, par);
-#if USE_CAPTION
-               }
-#endif
+               // FIXME: goddamn InsetTabular makes us pass a Buffer
+               // not BufferParams
+               unknown += ::readParagraph(*this, par, lex);
 
-       } else if (token == "\\end_inset") {
-               lyxerr << "Solitary \\end_inset in line " << lex.getLineNo() << "\n"
-                      << "Missing \\begin_inset?.\n";
-               // Simply ignore this. The insets do not have
-               // to read this.
-               // But insets should read it, it is a part of
-               // the inset isn't it? Lgb.
-       } else if (token == "\\begin_inset") {
-               readInset(lex, pit, pos, font, current_change);
-       } else if (token == "\\family") {
-               lex.next();
-               font.setLyXFamily(lex.getString());
-       } else if (token == "\\series") {
-               lex.next();
-               font.setLyXSeries(lex.getString());
-       } else if (token == "\\shape") {
-               lex.next();
-               font.setLyXShape(lex.getString());
-       } else if (token == "\\size") {
-               lex.next();
-               font.setLyXSize(lex.getString());
-       } else if (token == "\\lang") {
-               lex.next();
-               string const tok = lex.getString();
-               Language const * lang = languages.getLanguage(tok);
-               if (lang) {
-                       font.setLanguage(lang);
-               } else {
-                       font.setLanguage(params.language);
-                       lex.printError("Unknown language `$$Token'");
-               }
-       } else if (token == "\\numeric") {
-               lex.next();
-               font.setNumber(font.setLyXMisc(lex.getString()));
-       } else if (token == "\\emph") {
-               lex.next();
-               font.setEmph(font.setLyXMisc(lex.getString()));
-       } else if (token == "\\bar") {
-               lex.next();
-               string const tok = lex.getString();
-               // This is dirty, but gone with LyX3. (Asger)
-               if (tok == "under")
-                       font.setUnderbar(LyXFont::ON);
-               else if (tok == "no")
-                       font.setUnderbar(LyXFont::OFF);
-               else if (tok == "default")
-                       font.setUnderbar(LyXFont::INHERIT);
-               else
-                       lex.printError("Unknown bar font flag "
-                                      "`$$Token'");
-       } else if (token == "\\noun") {
-               lex.next();
-               font.setNoun(font.setLyXMisc(lex.getString()));
-       } else if (token == "\\color") {
-               lex.next();
-               font.setLyXColor(lex.getString());
-       } else if (token == "\\SpecialChar") {
-               LyXLayout_ptr const & layout = pit->layout();
-
-               // Insets don't make sense in a free-spacing context! ---Kayvan
-               if (layout->free_spacing || pit->isFreeSpacing()) {
-                       if (lex.isOK()) {
-                               lex.next();
-                               string const next_token = lex.getString();
-                               if (next_token == "\\-") {
-                                       pit->insertChar(pos, '-', font, current_change);
-                               } else if (next_token == "~") {
-                                       pit->insertChar(pos, ' ', font, current_change);
-                               } else {
-                                       lex.printError("Token `$$Token' "
-                                                      "is in free space "
-                                                      "paragraph layout!");
-                                       --pos;
-                               }
-                       }
-               } else {
-                       Inset * inset = new InsetSpecialChar;
-                       inset->read(this, lex);
-                       pit->insertInset(pos, inset, font, current_change);
-               }
-               ++pos;
-       } else if (token == "\\i") {
-               Inset * inset = new InsetLatexAccent;
-               inset->read(this, lex);
-               pit->insertInset(pos, inset, font, current_change);
-               ++pos;
-       } else if (token == "\\backslash") {
-               pit->insertChar(pos, '\\', font, current_change);
-               ++pos;
+               // insert after
+               if (pit != pars.end())
+                       ++pit;
+               pit = pars.insert(pit, par);
        } else if (token == "\\begin_deeper") {
                ++depth;
        } else if (token == "\\end_deeper") {
                if (!depth) {
-                       lex.printError("\\end_deeper: "
-                                      "depth is already null");
-               }
-               else
-                       --depth;
-       } else if (token == "\\noindent") {
-               pit->params().noindent(true);
-       } else if (token == "\\leftindent") {
-               lex.nextToken();
-               LyXLength value(lex.getString());
-               pit->params().leftIndent(value);
-       } else if (token == "\\fill_top") {
-               pit->params().spaceTop(VSpace(VSpace::VFILL));
-       } else if (token == "\\fill_bottom") {
-               pit->params().spaceBottom(VSpace(VSpace::VFILL));
-       } else if (token == "\\line_top") {
-               pit->params().lineTop(true);
-       } else if (token == "\\line_bottom") {
-               pit->params().lineBottom(true);
-       } else if (token == "\\pagebreak_top") {
-               pit->params().pagebreakTop(true);
-       } else if (token == "\\pagebreak_bottom") {
-               pit->params().pagebreakBottom(true);
-       } else if (token == "\\start_of_appendix") {
-               pit->params().startOfAppendix(true);
-       } else if (token == "\\paragraph_spacing") {
-               lex.next();
-               string const tmp = rtrim(lex.getString());
-               if (tmp == "single") {
-                       pit->params().spacing(Spacing(Spacing::Single));
-               } else if (tmp == "onehalf") {
-                       pit->params().spacing(Spacing(Spacing::Onehalf));
-               } else if (tmp == "double") {
-                       pit->params().spacing(Spacing(Spacing::Double));
-               } else if (tmp == "other") {
-                       lex.next();
-                       pit->params().spacing(Spacing(Spacing::Other,
-                                        lex.getFloat()));
+                       lex.printError("\\end_deeper: " "depth is already null");
                } else {
-                       lex.printError("Unknown spacing token: '$$Token'");
+                       --depth;
                }
-       } else if (token == "\\align") {
-               int tmpret = lex.findToken(string_align);
-               if (tmpret == -1)
-                       ++tmpret;
-               int const tmpret2 = int(pow(2.0, tmpret));
-               pit->params().align(LyXAlignment(tmpret2));
-       } else if (token == "\\added_space_top") {
-               lex.nextToken();
-               VSpace value = VSpace(lex.getString());
-               // only add the length when value > 0 or
-               // with option keep
-               if ((value.length().len().value() != 0) ||
-                   value.keep() ||
-                   (value.kind() != VSpace::LENGTH))
-                       pit->params().spaceTop(value);
-       } else if (token == "\\added_space_bottom") {
-               lex.nextToken();
-               VSpace value = VSpace(lex.getString());
-               // only add the length when value > 0 or
-               // with option keep
-               if ((value.length().len().value() != 0) ||
-                  value.keep() ||
-                   (value.kind() != VSpace::LENGTH))
-                       pit->params().spaceBottom(value);
-       } else if (token == "\\labelwidthstring") {
-               lex.eatLine();
-               pit->params().labelWidthString(lex.getString());
-               // do not delete this token, it is still needed!
-       } else if (token == "\\newline") {
-               pit->insertChar(pos, Paragraph::META_NEWLINE, font, current_change);
-               ++pos;
-       } else if (token == "\\LyXTable") {
-               Inset * inset = new InsetTabular(*this);
-               inset->read(this, lex);
-               pit->insertInset(pos, inset, font, current_change);
-               ++pos;
-       } else if (token == "\\bibitem") {  // ale970302
-               InsetCommandParams p("bibitem", "dummy");
-               InsetBibitem * inset = new InsetBibitem(p);
-               inset->read(this, lex);
-               pit->insertInset(pos, inset, font, current_change);
-               ++pos;
-       } else if (token == "\\hfill") {
-               pit->insertInset(pos, new InsetHFill(),
-                       LyXFont(LyXFont::ALL_INHERIT, params.language));
-               ++pos;
-       } else if (token == "\\change_unchanged") {
-               // Hack ! Needed for empty paragraphs :/
-               if (!pos)
-                       pit->cleanChanges();
-               current_change = Change(Change::UNCHANGED);
-       } else if (token == "\\change_inserted") {
-               lex.nextToken();
-               istringstream istr(lex.getString());
-               int aid;
-               lyx::time_type ct;
-               istr >> aid;
-               istr >> ct;
-               current_change = Change(Change::INSERTED, params.author_ids[aid], ct);
-       } else if (token == "\\change_deleted") {
-               lex.nextToken();
-               istringstream istr(lex.getString());
-               int aid;
-               lyx::time_type ct;
-               istr >> aid;
-               istr >> ct;
-               current_change = Change(Change::DELETED, params.author_ids[aid], ct);
        } else {
-               // This should be insurance for the future: (Asger)
                ++unknown;
-               lex.eatLine();
-#if USE_BOOST_FORMAT
-               boost::format fmt(_("Unknown token: %1$s %2$s\n"));
-               fmt % token % lex.text();
-               string const s = fmt.str();
-#else
-               string const s = _("Unknown token: ") + token
-                       + ' ' + lex.text() + '\n';
-#endif
-               // we can do this here this way because we're actually reading
-               // the buffer and don't care about LyXText right now.
-               InsetError * new_inset = new InsetError(s);
-               pit->insertInset(pos, new_inset, LyXFont(LyXFont::ALL_INHERIT,
-                                params.language));
-
        }
-
        return unknown;
 }
 
 
 // needed to insert the selection
-void Buffer::insertStringAsLines(Paragraph *& par, pos_type & pos,
+void Buffer::insertStringAsLines(ParagraphList::iterator & par, pos_type & pos,
                                 LyXFont const & fn,string const & str)
 {
        LyXLayout_ptr const & layout = par->layout();
@@ -798,7 +418,7 @@ void Buffer::insertStringAsLines(Paragraph *& par, pos_type & pos,
                        if (autobreakrows && (!par->empty() || layout->keepempty)) {
                                breakParagraph(params, paragraphs, par, pos,
                                               layout->isEnvironment());
-                               par = par->next();
+                               ++par;
                                pos = 0;
                                space_inserted = true;
                        } else {
@@ -838,213 +458,113 @@ void Buffer::insertStringAsLines(Paragraph *& par, pos_type & pos,
 }
 
 
-void Buffer::readInset(LyXLex & lex, ParagraphList::iterator pit,
-                      int & pos, LyXFont & font, Change current_change)
+bool Buffer::readFile(LyXLex & lex, string const & filename)
 {
-       // consistency check
-       if (lex.getString() != "\\begin_inset") {
-               lyxerr << "Buffer::readInset: Consistency check failed."
-                      << endl;
-       }
+       bool ret = readFile(lex, filename, paragraphs.begin());
 
-       Inset * inset = 0;
+       // After we have read a file, we must ensure that the buffer
+       // language is set and used in the gui.
+       // If you know of a better place to put this, please tell me. (Lgb)
+       updateDocLang(params.language);
+
+       return ret;
+}
 
-       lex.next();
-       string const tmptok = lex.getString();
-
-       // test the different insets
-       if (tmptok == "LatexCommand") {
-               InsetCommandParams inscmd;
-               inscmd.read(lex);
-
-               string const cmdName = inscmd.getCmdName();
-
-               // This strange command allows LyX to recognize "natbib" style
-               // citations: citet, citep, Citet etc.
-               if (compare_ascii_no_case(cmdName.substr(0,4), "cite") == 0) {
-                       inset = new InsetCitation(inscmd);
-               } else if (cmdName == "bibitem") {
-                       lex.printError("Wrong place for bibitem");
-                       inset = new InsetBibitem(inscmd);
-               } else if (cmdName == "BibTeX") {
-                       inset = new InsetBibtex(inscmd);
-               } else if (cmdName == "index") {
-                       inset = new InsetIndex(inscmd);
-               } else if (cmdName == "include") {
-                       inset = new InsetInclude(inscmd, *this);
-               } else if (cmdName == "label") {
-                       inset = new InsetLabel(inscmd);
-               } else if (cmdName == "url"
-                          || cmdName == "htmlurl") {
-                       inset = new InsetUrl(inscmd);
-               } else if (cmdName == "ref"
-                          || cmdName == "pageref"
-                          || cmdName == "vref"
-                          || cmdName == "vpageref"
-                          || cmdName == "prettyref") {
-                       if (!inscmd.getOptions().empty()
-                           || !inscmd.getContents().empty()) {
-                               inset = new InsetRef(inscmd, *this);
-                       }
-               } else if (cmdName == "tableofcontents") {
-                       inset = new InsetTOC(inscmd);
-               } else if (cmdName == "listofalgorithms") {
-                       inset = new InsetFloatList("algorithm");
-               } else if (cmdName == "listoffigures") {
-                       inset = new InsetFloatList("figure");
-               } else if (cmdName == "listoftables") {
-                       inset = new InsetFloatList("table");
-               } else if (cmdName == "printindex") {
-                       inset = new InsetPrintIndex(inscmd);
-               } else if (cmdName == "lyxparent") {
-                       inset = new InsetParent(inscmd, *this);
-               }
-       } else {
-               if (tmptok == "Quotes") {
-                       inset = new InsetQuotes;
-               } else if (tmptok == "External") {
-                       inset = new InsetExternal;
-               } else if (tmptok == "FormulaMacro") {
-                       inset = new InsetFormulaMacro;
-               } else if (tmptok == "Formula") {
-                       inset = new InsetFormula;
-               } else if (tmptok == "Graphics") {
-                       inset = new InsetGraphics;
-               } else if (tmptok == "Note") {
-                       inset = new InsetNote(params);
-               } else if (tmptok == "Include") {
-                       InsetCommandParams p("Include");
-                       inset = new InsetInclude(p, *this);
-               } else if (tmptok == "ERT") {
-                       inset = new InsetERT(params);
-               } else if (tmptok == "Tabular") {
-                       inset = new InsetTabular(*this);
-               } else if (tmptok == "Text") {
-                       inset = new InsetText(params);
-               } else if (tmptok == "Foot") {
-                       inset = new InsetFoot(params);
-               } else if (tmptok == "Marginal") {
-                       inset = new InsetMarginal(params);
-               } else if (tmptok == "OptArg") {
-                       inset = new InsetOptArg(params);
-               } else if (tmptok == "Minipage") {
-                       inset = new InsetMinipage(params);
-               } else if (tmptok == "Float") {
-                       lex.next();
-                       string tmptok = lex.getString();
-                       inset = new InsetFloat(params, tmptok);
-               } else if (tmptok == "Wrap") {
-                       lex.next();
-                       string tmptok = lex.getString();
-                       inset = new InsetWrap(params, tmptok);
-#if 0
-               } else if (tmptok == "List") {
-                       inset = new InsetList;
-               } else if (tmptok == "Theorem") {
-                       inset = new InsetList;
-#endif
-               } else if (tmptok == "Caption") {
-                       inset = new InsetCaption(params);
-               } else if (tmptok == "FloatList") {
-                       inset = new InsetFloatList;
-               }
 
-               if (inset)
-                       inset->read(this, lex);
+// FIXME: all the below Alerts should give the filename..
+bool Buffer::readFile(LyXLex & lex, string const & filename,
+                     ParagraphList::iterator pit)
+{
+       if (!lex.isOK()) {
+               Alert::error(_("Document could not be read"),
+                       _("The specified document could not be read."));
+               return false;
        }
 
-       if (inset) {
-               pit->insertInset(pos, inset, font, current_change);
-               ++pos;
+       lex.next();
+       string const token(lex.getString());
+
+       if (!lex.isOK()) {
+               Alert::error(_("Document could not be read"),
+                       _("The specified document could not be read."));
+               return false;
        }
-}
 
+       // the first token _must_ be...
+       if (token != "\\lyxformat") {
+               Alert::error(_("Document format failure"),
+                       _("The specified document is not a LyX document."));
+               return false;
+       }
 
-bool Buffer::readFile(LyXLex & lex, string const & filename)
-{
-       return readFile(lex, filename, paragraphs.begin());
-}
-
-
-bool Buffer::readFile(LyXLex & lex, string const & filename, ParagraphList::iterator pit)
-{
-       if (lex.isOK()) {
-               lex.next();
-               string const token(lex.getString());
-               if (token == "\\lyxformat") { // the first token _must_ be...
-                       lex.eatLine();
-                       string tmp_format = lex.getString();
-                       //lyxerr << "LyX Format: `" << tmp_format << '\'' << endl;
-                       // if present remove ".," from string.
-                       string::size_type dot = tmp_format.find_first_of(".,");
-                       //lyxerr << "           dot found at " << dot << endl;
-                       if (dot != string::npos)
-                               tmp_format.erase(dot, 1);
-                       file_format = strToInt(tmp_format);
-                       //lyxerr << "format: " << file_format << endl;
-                       if (file_format == LYX_FORMAT) {
-                               // current format
-                       } else if (file_format > LYX_FORMAT) {
-                               // future format
-                               Alert::alert(_("Warning!"),
-                                       _("The file was created with a newer version of "
-                                       "LyX. This is likely to cause problems."));
-
-                       } else if (file_format < LYX_FORMAT) {
-                               // old formats
-                               if (file_format < 200) {
-                                       Alert::alert(_("ERROR!"),
-                                                  _("Old LyX file format found. "
-                                                    "Use LyX 0.10.x to read this!"));
-                                       return false;
-                               } else if (!filename.empty()) {
-                                       string command =
-                                               LibFileSearch("lyx2lyx", "lyx2lyx");
-                                       if (command.empty()) {
-                                               Alert::alert(_("ERROR!"),
-                                                            _("Can't find conversion script."));
-                                               return false;
-                                       }
-                                       command += " -t"
-                                               +tostr(LYX_FORMAT) + ' '
-                                               + QuoteName(filename);
-                                       lyxerr[Debug::INFO] << "Running '"
-                                                           << command << '\''
-                                                           << endl;
-                                       cmd_ret const ret = RunCommand(command);
-                                       if (ret.first) {
-                                               Alert::alert(_("ERROR!"),
-                                                            _("An error occured while "
-                                                              "running the conversion script."));
-                                               return false;
-                                       }
-                                       istringstream is(STRCONV(ret.second));
-                                       LyXLex tmplex(0, 0);
-                                       tmplex.setStream(is);
-                                       return readFile(tmplex, string(), pit);
-                               } else {
-                                       // This code is reached if lyx2lyx failed (for
-                                       // some reason) to change the file format of
-                                       // the file.
-                                       lyx::Assert(false);
-                                       return false;
-                               }
+       lex.eatLine();
+       string tmp_format = lex.getString();
+       //lyxerr << "LyX Format: `" << tmp_format << '\'' << endl;
+       // if present remove ".," from string.
+       string::size_type dot = tmp_format.find_first_of(".,");
+       //lyxerr << "           dot found at " << dot << endl;
+       if (dot != string::npos)
+                       tmp_format.erase(dot, 1);
+       file_format = strToInt(tmp_format);
+       //lyxerr << "format: " << file_format << endl;
+       if (file_format == LYX_FORMAT) {
+               // current format
+       } else if (file_format > LYX_FORMAT) {
+               Alert::warning(_("Document format failure"),
+                       _("This document was created with a newer version of "
+                       "LyX. This is likely to cause problems."));
+       } else if (file_format < LYX_FORMAT) {
+               // old formats
+               if (file_format < 200) {
+                       Alert::error(_("Document format failure"),
+                               _("This LyX document is too old to be read "
+                               "by this version of LyX. Try LyX 0.10."));
+                       return false;
+               } else if (!filename.empty()) {
+                       string command =
+                               LibFileSearch("lyx2lyx", "lyx2lyx");
+                       if (command.empty()) {
+                               Alert::error(_("Conversion script not found"),
+                                       _("The document is from an earlier version "
+                                         "of LyX, but the conversion script lyx2lyx "
+                                         "could not be found."));
+                               return false;
                        }
-                       bool the_end = readBody(lex, pit);
-                       params.setPaperStuff();
-
-                       if (!the_end) {
-                               Alert::alert(_("Warning!"),
-                                          _("Reading of document is not complete"),
-                                          _("Maybe the document is truncated"));
+                       command += " -t"
+                               +tostr(LYX_FORMAT) + ' '
+                               + QuoteName(filename);
+                       lyxerr[Debug::INFO] << "Running '"
+                                           << command << '\''
+                                           << endl;
+                       cmd_ret const ret = RunCommand(command);
+                       if (ret.first) {
+                               Alert::error(_("Conversion script failed"),
+                                       _("The document is from an earlier version "
+                                         "of LyX, but the lyx2lyx script failed "
+                                         "to convert it."));
+                               return false;
                        }
-                       return true;
-               } else { // "\\lyxformat" not found
-                       Alert::alert(_("ERROR!"), _("Not a LyX file!"));
+                       istringstream is(STRCONV(ret.second));
+                       LyXLex tmplex(0, 0);
+                       tmplex.setStream(is);
+                       return readFile(tmplex, string(), pit);
+               } else {
+                       // This code is reached if lyx2lyx failed (for
+                       // some reason) to change the file format of
+                       // the file.
+                       lyx::Assert(false);
+                       return false;
                }
-       } else
-               Alert::alert(_("ERROR!"), _("Unable to read file!"));
-       return false;
+       }
+       bool the_end = readBody(lex, pit);
+       params.setPaperStuff();
+
+       if (!the_end) {
+               Alert::error(_("Document format failure"),
+                       _("The document ended unexpectedly, which means "
+                         "that it is probably corrupted."));
+       }
+       return true;
 }
 
 
@@ -1161,8 +681,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);
 
@@ -1275,9 +795,6 @@ string const Buffer::asciiParagraph(Paragraph const & par,
        /* noindent ? */
 
        /* what about the alignment */
-//     } else {
-//             lyxerr << "Should this ever happen?" << endl;
-//     }
 
        // linelen <= 0 is special and means we don't have paragraph breaks
 
@@ -1367,18 +884,6 @@ string const Buffer::asciiParagraph(Paragraph const & par,
                }
                break;
 
-               case Paragraph::META_NEWLINE:
-                       if (linelen > 0) {
-                               buffer << word << "\n";
-                               word.erase();
-
-                               pair<int, string> p = addDepth(depth,
-                                                              ltype_depth);
-                               buffer << p.second;
-                               currlinelen = p.first;
-                       }
-                       break;
-
                default:
                        if (c == ' ') {
                                if (linelen > 0 &&
@@ -1423,7 +928,9 @@ void Buffer::writeFileAscii(string const & fname, int linelen)
 {
        ofstream ofs(fname.c_str());
        if (!ofs) {
-               Alert::err_alert(_("Error: Cannot write file:"), fname);
+               string const file = MakeDisplayPath(fname, 50);
+               string text = bformat(_("Could not save the document\n%1$s."), file);
+               Alert::error(_("Could not save document"), text);
                return;
        }
        writeFileAscii(ofs, linelen);
@@ -1445,17 +952,22 @@ 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;
 
        ofstream ofs(fname.c_str());
        if (!ofs) {
-               Alert::err_alert(_("Error: Cannot open file: "), fname);
+               string const file = MakeDisplayPath(fname, 50);
+               string text = bformat(_("Could not open the specified document\n%1$s."),
+                       file);
+               Alert::error(_("Could not open file"), text);
                return;
        }
 
-       makeLaTeXFile(ofs, original_path, nice, only_body, only_preamble);
+       makeLaTeXFile(ofs, original_path,
+                     runparams, only_body, only_preamble);
 
        ofs.close();
        if (ofs.fail()) {
@@ -1466,9 +978,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;
@@ -1479,9 +993,9 @@ void Buffer::makeLaTeXFile(ostream & os,
        texrow.reset();
        // The starting paragraph of the coming rows is the
        // first paragraph of the document. (Asger)
-       texrow.start(&*(paragraphs.begin()), 0);
+       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 "
@@ -1498,7 +1012,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
@@ -1517,7 +1031,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;
@@ -1535,7 +1049,7 @@ void Buffer::makeLaTeXFile(ostream & os,
                texrow.newline();
        }
 
-       latexParagraphs(this, paragraphs, paragraphs.begin(), paragraphs.end(), os, texrow);
+       latexParagraphs(this, paragraphs, os, texrow, runparams);
 
        // add this just in case after all the paragraphs
        os << endl;
@@ -1608,7 +1122,10 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
        ofstream ofs(fname.c_str());
 
        if (!ofs) {
-               Alert::alert(_("LYX_ERROR:"), _("Cannot write file"), fname);
+               string const file = MakeDisplayPath(fname, 50);
+               string text = bformat(_("Could not save the specified document\n%1$s.\n"),
+                       file);
+               Alert::error(_("Could not save document"), text);
                return;
        }
 
@@ -1653,27 +1170,28 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
            << " -->\n";
 
        Paragraph::depth_type depth = 0; // paragraph depth
-       Paragraph * par = &*(paragraphs.begin());
        string item_name;
        vector<string> environment_stack(5);
 
-       while (par) {
-               LyXLayout_ptr const & style = par->layout();
+       users->resetErrorList();
+
+       ParagraphList::iterator pit = paragraphs.begin();
+       ParagraphList::iterator pend = paragraphs.end();
+       for (; pit != pend; ++pit) {
+               LyXLayout_ptr const & style = pit->layout();
                // treat <toc> as a special case for compatibility with old code
-               if (par->isInset(0)) {
-                       Inset * inset = par->getInset(0);
+               if (pit->isInset(0)) {
+                       Inset * inset = pit->getInset(0);
                        Inset::Code lyx_code = inset->lyxCode();
                        if (lyx_code == Inset::TOC_CODE) {
                                string const temp = "toc";
                                sgml::openTag(ofs, depth, false, temp);
-
-                               par = par->next();
                                continue;
                        }
                }
 
                // environment tag closing
-               for (; depth > par->params().depth(); --depth) {
+               for (; depth > pit->params().depth(); --depth) {
                        sgml::closeTag(ofs, depth, false, environment_stack[depth]);
                        environment_stack[depth].erase();
                }
@@ -1681,7 +1199,7 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
                // write opening SGML tags
                switch (style->latextype) {
                case LATEX_PARAGRAPH:
-                       if (depth == par->params().depth()
+                       if (depth == pit->params().depth()
                           && !environment_stack[depth].empty()) {
                                sgml::closeTag(ofs, depth, false, environment_stack[depth]);
                                environment_stack[depth].erase();
@@ -1694,8 +1212,8 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
                        break;
 
                case LATEX_COMMAND:
-                       if (depth!= 0)
-                               sgmlError(par, 0,
+                       if (depth != 0)
+                               sgmlError(pit, 0,
                                          _("Error: Wrong depth for LatexType Command.\n"));
 
                        if (!environment_stack[depth].empty()) {
@@ -1713,14 +1231,14 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
                {
                        string const & latexname = style->latexname();
 
-                       if (depth == par->params().depth()
+                       if (depth == pit->params().depth()
                            && environment_stack[depth] != latexname) {
                                sgml::closeTag(ofs, depth, false,
                                             environment_stack[depth]);
                                environment_stack[depth].erase();
                        }
-                       if (depth < par->params().depth()) {
-                              depth = par->params().depth();
+                       if (depth < pit->params().depth()) {
+                              depth = pit->params().depth();
                               environment_stack[depth].erase();
                        }
                        if (environment_stack[depth] != latexname) {
@@ -1753,9 +1271,7 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
                        break;
                }
 
-               simpleLinuxDocOnePar(ofs, par, depth);
-
-               par = par->next();
+               simpleLinuxDocOnePar(ofs, pit, depth);
 
                ofs << "\n";
                // write closing SGML tags
@@ -1788,6 +1304,8 @@ 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"));
 }
 
 
@@ -1848,8 +1366,8 @@ void reset(PAR_TAG & p1, PAR_TAG const & p2)
 
 // Handle internal paragraph parsing -- layout already processed.
 void Buffer::simpleLinuxDocOnePar(ostream & os,
-       Paragraph * par,
-       Paragraph::depth_type /*depth*/)
+       ParagraphList::iterator par,
+       Paragraph::depth_type /*depth*/) const
 {
        LyXLayout_ptr const & style = par->layout();
 
@@ -1878,7 +1396,7 @@ void Buffer::simpleLinuxDocOnePar(ostream & os,
                PAR_TAG tag_close = NONE;
                list < PAR_TAG > tag_open;
 
-               LyXFont const font = par->getFont(params, i);
+               LyXFont const font = par->getFont(params, i, outerFont(par, paragraphs));
 
                if (font_old.family() != font.family()) {
                        switch (family_type) {
@@ -2041,23 +1559,10 @@ void Buffer::simpleLinuxDocOnePar(ostream & os,
 
 
 // Print an error message.
-void Buffer::sgmlError(Paragraph * /*par*/, int /*pos*/,
-       string const & /*message*/) const
-{
-#ifdef WITH_WARNINGS
-#warning This is wrong we cannot insert an inset like this!!!
-       // I guess this was Jose' so I explain you more or less why this
-       // is wrong. This way you insert something in the paragraph and
-       // don't tell it to LyXText (row rebreaking and undo handling!!!)
-       // I deactivate this code, have a look at BufferView::insertErrors
-       // how you should do this correctly! (Jug 20020315)
-#endif
-#if 0
-       // insert an error marker in text
-       InsetError * new_inset = new InsetError(message);
-       par->insertInset(pos, new_inset, LyXFont(LyXFont::ALL_INHERIT,
-                        params.language));
-#endif
+void Buffer::sgmlError(ParagraphList::iterator pit, int pos,
+                      string const & message) const
+{
+       users->addError(ErrorItem(message, string(), pit->id(), pos, pos));
 }
 
 
@@ -2065,12 +1570,13 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
 {
        ofstream ofs(fname.c_str());
        if (!ofs) {
-               Alert::alert(_("LYX_ERROR:"), _("Cannot write file"), fname);
+               string const file = MakeDisplayPath(fname, 50);
+               string text = bformat(_("Could not save the specified document\n%1$s.\n"),
+                       file);
+               Alert::error(_("Could not save document"), text);
                return;
        }
 
-       Paragraph * par = &*(paragraphs.begin());
-
        niceFile = nice; // this will be used by Insetincludes.
 
        LaTeXFeatures features(params);
@@ -2124,7 +1630,12 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
        string item_name;
        string command_name;
 
-       while (par) {
+       users->resetErrorList();
+
+       ParagraphList::iterator par = paragraphs.begin();
+       ParagraphList::iterator pend = paragraphs.end();
+
+       for (; par != pend; ++par) {
                string sgmlparam;
                string c_depth;
                string c_params;
@@ -2278,7 +1789,6 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
 
                simpleDocBookOnePar(ofs, par, desc_on,
                                    depth + 1 + command_depth);
-               par = par->next();
 
                string end_tag;
                // write closing SGML tags
@@ -2338,11 +1848,12 @@ 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"));
 }
 
 
 void Buffer::simpleDocBookOnePar(ostream & os,
-                                Paragraph * par, int & desc_on,
+                                ParagraphList::iterator par, int & desc_on,
                                 Paragraph::depth_type depth) const
 {
        bool emph_flag = false;
@@ -2357,7 +1868,7 @@ void Buffer::simpleDocBookOnePar(ostream & os,
 
        // parsing main loop
        for (pos_type i = 0; i < par->size(); ++i) {
-               LyXFont font = par->getFont(params, i);
+               LyXFont font = par->getFont(params, i, outerFont(par, paragraphs));
 
                // handle <emphasis> tag
                if (font_old.emph() != font.emph()) {
@@ -2448,31 +1959,26 @@ 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());
        int res = chktex.run(terr); // run chktex
 
        if (res == -1) {
-               Alert::alert(_("chktex did not work!"),
-                          _("Could not run with file:"), name);
+               Alert::error(_("chktex failure"),
+                       _("Could not run chktex successfully."));
        } else if (res > 0) {
                // Insert all errors as errors boxes
-               users->insertErrors(terr);
+               ErrorList el (*this, terr);
+               users->setErrorList(el);
+               users->showErrorList(_("ChkTeX"));
        }
 
-       // 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;
@@ -2641,6 +2147,10 @@ void Buffer::redraw()
 
 void Buffer::changeLanguage(Language const * from, Language const * to)
 {
+       lyxerr << "Changing Language!" << endl;
+
+       // Take care of l10n/i18n
+       updateDocLang(to);
 
        ParIterator end = par_iterator_end();
        for (ParIterator it = par_iterator_begin(); it != end; ++it)
@@ -2648,6 +2158,12 @@ void Buffer::changeLanguage(Language const * from, Language const * to)
 }
 
 
+void Buffer::updateDocLang(Language const * nlang)
+{
+       messages_.reset(new Messages(nlang->code()));
+}
+
+
 bool Buffer::isMultiLingual()
 {
        ParIterator end = par_iterator_end();
@@ -2685,49 +2201,66 @@ Inset * Buffer::getInsetFromID(int id_arg) const
 }
 
 
-Paragraph * Buffer::getParFromID(int id) const
+ParIterator Buffer::getParFromID(int id) const
 {
-       if (id < 0)
-               return 0;
+#warning FIXME: const correctness! (Andre)
+       ParIterator it = const_cast<Buffer*>(this)->par_iterator_begin();
+       ParIterator end = const_cast<Buffer*>(this)->par_iterator_end();
 
-       // why should we allow < 0 ??
-       //lyx::Assert(id >= 0);
+#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 end;
+       }
 
-       ParConstIterator it(par_iterator_begin());
-       ParConstIterator end(par_iterator_end());
+       for (; it != end; ++it)
+               if ((*it)->id() == id)
+                       return it;
 
-       for (; it != end; ++it) {
-               // go on then, show me how to remove
-               // the cast
-               if ((*it)->id() == id) {
-                       return const_cast<Paragraph*>(*it);
-               }
+       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());
+
+       if (id < 0) {
+               // John says this is called with id == -1 from undo
+               lyxerr << "hasParWithID(), id: " << id << endl;
+               return 0;
        }
 
-       return 0;
+       for (; it != end; ++it)
+               if ((*it)->id() == id)
+                       return true;
+
+       return false;
 }
 
 
 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);
 }
 
 
@@ -2750,6 +2283,16 @@ Language const * Buffer::getLanguage() const
 }
 
 
+string const Buffer::B_(string const & l10n) const
+{
+       if (messages_.get()) {
+               return messages_->get(l10n);
+       }
+
+       return _(l10n);
+}
+
+
 bool Buffer::isClean() const
 {
        return lyx_clean;
@@ -2840,7 +2383,7 @@ void Buffer::setParentName(string const & name)
 
 
 Buffer::inset_iterator::inset_iterator()
-       : pit(0), pend(0)
+       : pit(), pend()
 {}
 
 
@@ -2874,25 +2417,25 @@ 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;
 }
 
 
-Paragraph * Buffer::inset_iterator::getPar()
+ParagraphList::iterator Buffer::inset_iterator::getPar() const
 {
-       return &(*pit);
+       return pit;
 }
 
 
 lyx::pos_type Buffer::inset_iterator::getPos() const
 {
-       return it.getPos();
+       return it->pos;
 }