]> git.lyx.org Git - lyx.git/blobdiff - src/buffer.C
Alfredo's second patch
[lyx.git] / src / buffer.C
index 358f27bc53615e18b34df29924d56f96d4bab5dd..3e1841f0e39e2799afde65f34200f37be0277b99 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>
@@ -40,6 +36,7 @@
 #include "lyxtextclasslist.h"
 #include "sgml.h"
 #include "paragraph_funcs.h"
+#include "messages.h"
 #include "author.h"
 
 #include "frontends/LyXView.h"
@@ -69,7 +66,7 @@
 
 #include <boost/bind.hpp>
 #include <boost/tuple/tuple.hpp>
-#include "BoostFormat.h"
+#include "support/BoostFormat.h"
 
 #include <fstream>
 #include <iomanip>
@@ -149,8 +146,15 @@ Buffer::~Buffer()
        if (users)
                users->buffer(0);
 
-       if (!tmppath.empty()) {
-               DestroyBufferTmpDir(tmppath);
+       if (!tmppath.empty() && destroyDir(tmppath) != 0) {
+#if USE_BOOST_FORMAT
+               boost::format fmt = _("Could not remove the temporary directory %1$s");
+               fmt % tmppath;
+               string msg = fmt.str();
+#else
+               string msg = _("Could not remove the temporary directory ") + tmppath;
+#endif
+               Alert::warning(_("Could not remove temporary directory"), msg);
        }
 
        paragraphs.clear();
@@ -251,23 +255,18 @@ 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.");
+                       _("Using the default document class, because the "
+                       " class %1$s is unknown.")) % unknown);
 #else
-               _("The document uses an unknown textclass ")
-               + unknown + _("-- substituting default.");
+               _("Using the default document class, because the "
+               " class ") + unknown + (" is unknown.");
 #endif
-       Alert::alert(_("Textclass error"), msg);
+       Alert::warning(_("Unknown document class"), msg);
 }
 
 } // anon
@@ -294,7 +293,7 @@ int Buffer::readHeader(LyXLex & lex)
                        if (unknown[0] != '\\') {
                                unknownClass(unknown);
                        } else {
-                       ++unknown_tokens;
+                               ++unknown_tokens;
                        }
                }
        }
@@ -312,7 +311,6 @@ 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;
 
        Paragraph::depth_type depth = 0;
@@ -322,23 +320,22 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
                unknown_tokens += readHeader(lex);
 
                if (!params.getLyXTextClass().load()) {
+                       string theclass = params.getLyXTextClass().name();
+                       string msg =
 #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."));
+                               boost::io::str(boost::format(
+                                       _("Using the default document class, because the "
+                                       " class %1$s could not be loaded.")) % theclass);
 #else
-                       Alert::alert(_("Textclass Loading Error!"),
-                                    _("Can't load textclass ")
-                                    + params.getLyXTextClass().name(),
-                                    _("-- substituting default."));
+                               _("Using the default document class, because the "
+                               " class ") + theclass + (" could not be loaded.");
 #endif
+                       Alert::error(_("Can't load document class"), msg);
                        params.textclass = 0;
                }
        } else {
                // We are inserting into an existing document
                users->text->breakParagraph(paragraphs);
-               markDirty();
 
                // We don't want to adopt the parameters from the
                // document we insert, so read them into a temporary buffer
@@ -366,24 +363,21 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
                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");
+
+       if (unknown_tokens > 0) {
+#if USE_BOOST_FORMAT
+               string s;
+               if (unknown_tokens == 1) {
+                       boost::format fmt(_("Encountered one unknown token when reading the document %1$s."));
+                       fmt % fileName();
+                       s = fmt.str();
                } else {
-                       s += tostr(unknown_layouts);
-                       s += _(" paragraphs");
+                       boost::format fmt(_("Encountered %1$s unknown tokens when reading the document %2$s."));
+                       fmt % tostr(unknown_tokens);
+                       fmt % fileName();
+                       s = fmt.str();
                }
-#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 ");
                if (unknown_tokens == 1) {
                        s += _("one unknown token");
@@ -391,12 +385,7 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
                        s += tostr(unknown_tokens);
                        s += _(" unknown tokens");
                }
-#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());
+               Alert::warning(_("Document format failure"), s);
 #endif
        }
 
@@ -446,7 +435,7 @@ Buffer::readParagraph(LyXLex & lex, string const & token,
 
 
 // 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();
@@ -464,7 +453,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 {
@@ -506,89 +495,111 @@ void Buffer::insertStringAsLines(Paragraph *& par, pos_type & pos,
 
 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;
-                               }
-                       }
-                       bool the_end = readBody(lex, pit);
-                       params.setPaperStuff();
+       bool ret = readFile(lex, filename, paragraphs.begin());
+
+       // 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;
+}
+
+
+// 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;
+       }
+
+       lex.next();
+       string const token(lex.getString());
 
-                       if (!the_end) {
-                               Alert::alert(_("Warning!"),
-                                          _("Reading of document is not complete"),
-                                          _("Maybe the document is truncated"));
+       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;
+       }
+
+       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;
                        }
-                       return true;
-               } else { // "\\lyxformat" not found
-                       Alert::alert(_("ERROR!"), _("Not a LyX file!"));
+                       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;
+                       }
+                       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;
 }
 
 
@@ -819,9 +830,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
 
@@ -955,7 +963,16 @@ 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);
+#if USE_BOOST_FORMAT
+               boost::format fmt(_("Could not save the document\n%1$s."));
+               fmt % file;
+               string text = fmt.str();
+#else
+               string text = _("Could not save the document\n");
+               text += file + ".";
+#endif
+               Alert::error(_("Could not save document"), text);
                return;
        }
        writeFileAscii(ofs, linelen);
@@ -983,7 +1000,16 @@ void Buffer::makeLaTeXFile(string const & fname,
 
        ofstream ofs(fname.c_str());
        if (!ofs) {
-               Alert::err_alert(_("Error: Cannot open file: "), fname);
+               string const file = MakeDisplayPath(fname, 50);
+#if USE_BOOST_FORMAT
+               boost::format fmt(_("Could not open the specified document\n%1$s."));
+               fmt % file;
+               string text = fmt.str();
+#else
+               string text = _("Could not open the specified document\n");
+               text += file + ".";
+#endif
+               Alert::error(_("Could not open file"), text);
                return;
        }
 
@@ -1140,7 +1166,16 @@ 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);
+#if USE_BOOST_FORMAT
+               boost::format fmt(_("Could not save the specified document\n%1$s.\n"));
+               fmt % file;
+               string text = fmt.str();
+#else
+               string text = _("Could not save the specified document\n");
+               text += file + _(".\n");
+#endif
+               Alert::error(_("Could not save document"), text);
                return;
        }
 
@@ -1185,27 +1220,26 @@ 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();
+       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();
                }
@@ -1213,7 +1247,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();
@@ -1226,8 +1260,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()) {
@@ -1245,14 +1279,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) {
@@ -1285,9 +1319,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
@@ -1410,7 +1442,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) {
@@ -1573,7 +1605,7 @@ void Buffer::simpleLinuxDocOnePar(ostream & os,
 
 
 // Print an error message.
-void Buffer::sgmlError(Paragraph * /*par*/, int /*pos*/,
+void Buffer::sgmlError(ParagraphList::iterator /*par*/, int /*pos*/,
        string const & /*message*/) const
 {
 #ifdef WITH_WARNINGS
@@ -1597,12 +1629,19 @@ 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);
+#if USE_BOOST_FORMAT
+               boost::format fmt(_("Could not save the specified document\n%1$s.\n"));
+               fmt % file;
+               string text = fmt.str();
+#else
+               string text = _("Could not save the specified document\n");
+               text += file + _(".\n");
+#endif
+               Alert::error(_("Could not save document"), text);
                return;
        }
 
-       Paragraph * par = &*(paragraphs.begin());
-
        niceFile = nice; // this will be used by Insetincludes.
 
        LaTeXFeatures features(params);
@@ -1656,7 +1695,10 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
        string item_name;
        string command_name;
 
-       while (par) {
+       ParagraphList::iterator par = paragraphs.begin();
+       ParagraphList::iterator pend = paragraphs.end();
+
+       for (; par != pend; ++par) {
                string sgmlparam;
                string c_depth;
                string c_params;
@@ -1810,7 +1852,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
@@ -1874,7 +1915,7 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
 
 
 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;
@@ -1889,7 +1930,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()) {
@@ -1991,8 +2032,8 @@ int Buffer::runChktex()
        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);
@@ -2173,6 +2214,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)
@@ -2180,6 +2225,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();
@@ -2217,22 +2268,24 @@ Inset * Buffer::getInsetFromID(int id_arg) const
 }
 
 
-Paragraph * Buffer::getParFromID(int id) const
+ParagraphList::iterator Buffer::getParFromID(int id) const
 {
-       if (id < 0)
-               return 0;
-
-       // why should we allow < 0 ??
-       //lyx::Assert(id >= 0);
+#warning FIXME: const correctness! (Andre)
+       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());
+#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;
+       }
 
        for (; it != end; ++it) {
                // go on then, show me how to remove
                // the cast
                if ((*it)->id() == id) {
-                       return const_cast<Paragraph*>(*it);
+                       return *it;
                }
        }
 
@@ -2282,6 +2335,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;