]> git.lyx.org Git - lyx.git/blobdiff - src/buffer.C
"Inter-word Space"
[lyx.git] / src / buffer.C
index f7b0aae7623405cf549ea55a39b3fe0f09193ad3..2200f0dc84d9835d1c34e356a3d5ff6634ea5bf5 100644 (file)
@@ -28,6 +28,7 @@
 #include "gettext.h"
 #include "language.h"
 #include "exporter.h"
+#include "errorlist.h"
 #include "Lsstream.h"
 #include "format.h"
 #include "BufferView.h"
@@ -36,6 +37,7 @@
 #include "lyxtextclasslist.h"
 #include "sgml.h"
 #include "paragraph_funcs.h"
+#include "messages.h"
 #include "author.h"
 
 #include "frontends/LyXView.h"
@@ -58,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"
@@ -65,7 +68,6 @@
 
 #include <boost/bind.hpp>
 #include <boost/tuple/tuple.hpp>
-#include "support/BoostFormat.h"
 
 #include <fstream>
 #include <iomanip>
@@ -146,14 +148,8 @@ Buffer::~Buffer()
                users->buffer(0);
 
        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);
+               Alert::warning(_("Could not remove temporary directory"),
+                       bformat(_("Could not remove the temporary directory %1$s"), tmppath));
        }
 
        paragraphs.clear();
@@ -166,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;
 }
 
 
@@ -256,16 +249,9 @@ namespace {
 
 void unknownClass(string const & unknown)
 {
-       string msg =
-#if USE_BOOST_FORMAT
-               boost::io::str(boost::format(
-                       _("Using the default document class, because the "
-                       " class %1$s is unknown.")) % unknown);
-#else
-               _("Using the default document class, because the "
-               " class ") + unknown + (" is unknown.");
-#endif
-       Alert::warning(_("Unknown document class"), msg);
+       Alert::warning(_("Unknown document class"),
+               bformat(_("Using the default document class, because the "
+                       " class %1$s is unknown."), unknown));
 }
 
 } // anon
@@ -320,16 +306,9 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
 
                if (!params.getLyXTextClass().load()) {
                        string theclass = params.getLyXTextClass().name();
-                       string msg =
-#if USE_BOOST_FORMAT
-                               boost::io::str(boost::format(
-                                       _("Using the default document class, because the "
-                                       " class %1$s could not be loaded.")) % theclass);
-#else
-                               _("Using the default document class, because the "
-                               " class ") + theclass + (" could not be loaded.");
-#endif
-                       Alert::error(_("Can't load document class"), msg);
+                       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 {
@@ -364,36 +343,22 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
 
 
        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();
+                       s = bformat(_("Encountered one unknown token when reading "
+                               "the document %1$s."), fileName());
                } else {
-                       boost::format fmt(_("Encountered %1$s unknown tokens when reading the document %2$s."));
-                       fmt % tostr(unknown_tokens);
-                       fmt % fileName();
-                       s = fmt.str();
-               }
-#else
-               string s = _("Encountered ");
-               if (unknown_tokens == 1) {
-                       s += _("one unknown token");
-               } 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());
                }
                Alert::warning(_("Document format failure"), s);
-#endif
        }
 
        return the_end_read;
 }
 
 
-int
-Buffer::readParagraph(LyXLex & lex, string const & token,
+int Buffer::readParagraph(LyXLex & lex, string const & token,
                      ParagraphList & pars, ParagraphList::iterator & pit,
                      Paragraph::depth_type & depth)
 {
@@ -403,16 +368,17 @@ Buffer::readParagraph(LyXLex & lex, string const & token,
        if (token == "\\layout") {
                lex.pushToken(token);
 
-               Paragraph * par = new Paragraph();
-               par->params().depth(depth);
+               Paragraph par;
+               par.owningBuffer(*this);
+               par.params().depth(depth);
                if (params.tracking_changes)
-                       par->trackChanges();
+                       par.trackChanges();
                LyXFont f(LyXFont::ALL_INHERIT, params.language);
-               par->setFont(0, f);
+               par.setFont(0, f);
 
                // FIXME: goddamn InsetTabular makes us pass a Buffer
                // not BufferParams
-               unknown += ::readParagraph(*this, *par, lex);
+               unknown += ::readParagraph(*this, par, lex);
 
                // insert after
                if (pit != pars.end())
@@ -494,12 +460,20 @@ void Buffer::insertStringAsLines(ParagraphList::iterator & par, pos_type & pos,
 
 bool Buffer::readFile(LyXLex & lex, string const & filename)
 {
-       return readFile(lex, filename, paragraphs.begin());
+       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)
+bool Buffer::readFile(LyXLex & lex, string const & filename,
+                     ParagraphList::iterator pit)
 {
        if (!lex.isOK()) {
                Alert::error(_("Document could not be read"),
@@ -707,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);
 
@@ -955,14 +929,7 @@ void Buffer::writeFileAscii(string const & fname, int linelen)
        ofstream ofs(fname.c_str());
        if (!ofs) {
                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
+               string text = bformat(_("Could not save the document\n%1$s."), file);
                Alert::error(_("Could not save document"), text);
                return;
        }
@@ -985,26 +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) {
                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
+               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()) {
@@ -1015,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;
@@ -1028,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 "
@@ -1047,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
@@ -1066,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;
@@ -1084,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;
@@ -1158,14 +1123,8 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
 
        if (!ofs) {
                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
+               string text = bformat(_("Could not save the specified document\n%1$s.\n"),
+                       file);
                Alert::error(_("Could not save document"), text);
                return;
        }
@@ -1214,6 +1173,8 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
        string item_name;
        vector<string> environment_stack(5);
 
+       users->resetErrorList();
+
        ParagraphList::iterator pit = paragraphs.begin();
        ParagraphList::iterator pend = paragraphs.end();
        for (; pit != pend; ++pit) {
@@ -1252,7 +1213,7 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
 
                case LATEX_COMMAND:
                        if (depth != 0)
-                               sgmlError(&*pit, 0,
+                               sgmlError(pit, 0,
                                          _("Error: Wrong depth for LatexType Command.\n"));
 
                        if (!environment_stack[depth].empty()) {
@@ -1310,7 +1271,7 @@ void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
                        break;
                }
 
-               simpleLinuxDocOnePar(ofs, &*pit, depth);
+               simpleLinuxDocOnePar(ofs, pit, depth);
 
                ofs << "\n";
                // write closing SGML tags
@@ -1343,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"));
 }
 
 
@@ -1403,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();
 
@@ -1596,23 +1559,10 @@ void Buffer::simpleLinuxDocOnePar(ostream & os,
 
 
 // Print an error message.
-void Buffer::sgmlError(ParagraphList::iterator /*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));
 }
 
 
@@ -1621,17 +1571,10 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
        ofstream ofs(fname.c_str());
        if (!ofs) {
                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
+               string text = bformat(_("Could not save the specified document\n%1$s.\n"),
+                       file);
                Alert::error(_("Could not save document"), text);
                return;
-               return;
        }
 
        niceFile = nice; // this will be used by Insetincludes.
@@ -1687,6 +1630,8 @@ void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
        string item_name;
        string command_name;
 
+       users->resetErrorList();
+
        ParagraphList::iterator par = paragraphs.begin();
        ParagraphList::iterator pend = paragraphs.end();
 
@@ -1903,6 +1848,7 @@ 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"));
 }
 
 
@@ -2013,11 +1959,11 @@ int Buffer::runChktex()
        Path p(path); // path to LaTeX file
        users->owner()->message(_("Running chktex..."));
 
-       // Remove all error insets
-       bool const removedErrorInsets = users->removeAutoInsets();
-
        // Generate the LaTeX file if neccessary
-       makeLaTeXFile(name, org_path, false);
+       LatexRunParams runparams;
+       runparams.flavor = LatexRunParams::LATEX;
+       runparams.nice = false;
+       makeLaTeXFile(name, org_path, runparams);
 
        TeXErrors terr;
        Chktex chktex(lyxrc.chktex_command, name, filePath());
@@ -2028,16 +1974,11 @@ int Buffer::runChktex()
                        _("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;
@@ -2206,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)
@@ -2213,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();
@@ -2250,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);
 }
 
 
@@ -2315,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;
@@ -2405,7 +2383,7 @@ void Buffer::setParentName(string const & name)
 
 
 Buffer::inset_iterator::inset_iterator()
-       : pit(0), pend(0)
+       : pit(), pend()
 {}
 
 
@@ -2439,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;
 }