]> git.lyx.org Git - lyx.git/blobdiff - src/Text.cpp
Update my email and status.
[lyx.git] / src / Text.cpp
index 25f58d55dd89a1915e6a6592b12da989f90f8d7e..48f8c82491fc40db4c3f867a5a52fb6e7a67848f 100644 (file)
@@ -46,7 +46,6 @@
 #include "ParIterator.h"
 #include "TextClass.h"
 #include "TextMetrics.h"
-#include "VSpace.h"
 #include "WordLangTuple.h"
 #include "WordList.h"
 
 #include "insets/InsetNewline.h"
 #include "insets/InsetNewpage.h"
 #include "insets/InsetArgument.h"
+#include "insets/InsetIPAMacro.h"
 #include "insets/InsetSpace.h"
 #include "insets/InsetSpecialChar.h"
 #include "insets/InsetTabular.h"
 
+#include "support/convert.h"
 #include "support/debug.h"
 #include "support/docstream.h"
 #include "support/gettext.h"
 
 #include <boost/next_prior.hpp>
 
+#include <limits>
 #include <sstream>
 
+
+// TODO: replace if in Text::readParToken() with compile time switch
+#if 0
+
+#include "support/metahash.h"
+
+typedef boost::mpl::string<'\\end','_lay','out'> end_layout;
+typedef boost::mpl::string<'\\end','in','set'>   end_inset;
+
+void foo()
+{
+       std::string token = "\\end_layout";
+
+       switch (boost::hash_value(token)) {
+               case lyx::support::hash_string<end_layout>::value:
+                       return;
+               case lyx::support::hash_string<end_inset>::value:
+                       return;
+               default: ;
+       };
+
+}
+#endif
+
+
 using namespace std;
 using namespace lyx::support;
 
@@ -238,15 +265,28 @@ bool Text::isFirstInSequence(pit_type par_offset) const
 }
 
 
+int Text::getTocLevel(pit_type par_offset) const
+{
+       Paragraph const & par = pars_[par_offset];
+
+       if (par.layout().isEnvironment() && !isFirstInSequence(par_offset))
+               return Layout::NOT_IN_TOC;
+
+       return par.layout().toclevel;
+}
+
+
 Font const Text::outerFont(pit_type par_offset) const
 {
        depth_type par_depth = pars_[par_offset].getDepth();
        FontInfo tmpfont = inherit_font;
-
+       depth_type prev_par_depth = 0;
        // Resolve against environment font information
        while (par_offset != pit_type(pars_.size())
+              && par_depth != prev_par_depth
               && par_depth
               && !tmpfont.resolved()) {
+               prev_par_depth = par_depth;
                par_offset = outerHook(par_offset);
                if (par_offset != pit_type(pars_.size())) {
                        tmpfont.realize(pars_[par_offset].layout().font);
@@ -317,6 +357,7 @@ InsetText const & Text::inset() const
 }
 
 
+
 void Text::readParToken(Paragraph & par, Lexer & lex,
        string const & token, Font & font, Change & change, ErrorList & errorList)
 {
@@ -356,7 +397,13 @@ void Text::readParToken(Paragraph & par, Lexer & lex,
                // of this document. For example, when you apply class article to a beamer document,
                // all unknown layouts such as frame will be added to document class article so that
                // these layouts can keep their original names.
-               tclass.addLayoutIfNeeded(layoutname);
+               bool const added_one = tclass.addLayoutIfNeeded(layoutname);
+               if (added_one) {
+                       // Warn the user.
+                       docstring const s = bformat(_("Layout `%1$s' was not found."), layoutname);
+                       errorList.push_back(
+                               ErrorItem(_("Layout Not Found"), s, par.id(), 0, par.size()));
+               }
 
                par.setLayout(bp.documentClass()[layoutname]);
 
@@ -445,6 +492,12 @@ void Text::readParToken(Paragraph & par, Lexer & lex,
                inset->read(lex);
                inset->setBuffer(*buf);
                par.insertInset(par.size(), inset.release(), font, change);
+       } else if (token == "\\IPAChar") {
+               auto_ptr<Inset> inset;
+               inset.reset(new InsetIPAChar);
+               inset->read(lex);
+               inset->setBuffer(*buf);
+               par.insertInset(par.size(), inset.release(), font, change);
        } else if (token == "\\backslash") {
                par.appendChar('\\', font, change);
        } else if (token == "\\LyXTable") {
@@ -690,8 +743,7 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
                return;
        }
 
-       // a layout change may affect also the following paragraph
-       recUndo(cur, cur.pit(), undoSpan(cur.pit()) - 1);
+       cur.recordUndo();
 
        // Always break behind a space
        // It is better to erase the space (Dekel)
@@ -749,12 +801,12 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
 
 
 // needed to insert the selection
-void Text::insertStringAsLines(DocIterator const & dit, docstring const & str,
+void Text::insertStringAsLines(Cursor & cur, docstring const & str,
                Font const & font)
 {
        BufferParams const & bparams = owner_->buffer().params();
-       pit_type pit = dit.pit();
-       pos_type pos = dit.pos();
+       pit_type pit = cur.pit();
+       pos_type pos = cur.pos();
 
        // insert the string, don't insert doublespace
        bool space_inserted = true;
@@ -796,12 +848,13 @@ void Text::insertStringAsLines(DocIterator const & dit, docstring const & str,
                        space_inserted = (*cit == ' ');
                }
        }
+       setCursor(cur, pit, pos);
 }
 
 
 // turn double CR to single CR, others are converted into one
 // blank. Then insertStringAsLines is called
-void Text::insertStringAsParagraphs(DocIterator const & dit, docstring const & str,
+void Text::insertStringAsParagraphs(Cursor & cur, docstring const & str,
                Font const & font)
 {
        docstring linestr = str;
@@ -823,7 +876,7 @@ void Text::insertStringAsParagraphs(DocIterator const & dit, docstring const & s
                        newline_inserted = false;
                }
        }
-       insertStringAsLines(dit, linestr, font);
+       insertStringAsLines(cur, linestr, font);
 }
 
 
@@ -1243,7 +1296,11 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
 
                pos_type left  = (pit == begPit ? begPos : 0);
                pos_type right = (pit == endPit ? endPos : parSize);
-
+               
+               if (left == right)
+                       // there is no change here
+                       continue;
+               
                if (op == ACCEPT) {
                        pars_[pit].acceptChanges(left, right);
                } else {
@@ -1641,13 +1698,23 @@ bool Text::dissolveInset(Cursor & cur)
        spit += cur.pit();
        Buffer & b = *cur.buffer();
        cur.paragraph().eraseChar(cur.pos(), b.params().trackChanges);
+
        if (!plist.empty()) {
+               // see bug 7319
+               // we clear the cache so that we won't get conflicts with labels
+               // that get pasted into the buffer. we should update this before
+               // its being empty matters. if not (i.e., if we encounter bugs),
+               // then this should instead be:
+               //        cur.buffer().updateBuffer();
+               // but we'll try the cheaper solution here.
+               cur.buffer()->clearReferenceCache();
+
                // ERT paragraphs have the Language latex_language.
                // This is invalid outside of ERT, so we need to
                // change it to the buffer language.
                ParagraphList::iterator it = plist.begin();
                ParagraphList::iterator it_end = plist.end();
-               for (; it != it_end; it++)
+               for (; it != it_end; ++it)
                        it->changeLanguage(b.params(), latex_language, b.language());
 
                pasteParagraphList(cur, plist, b.params().documentClassPtr(),
@@ -1655,8 +1722,9 @@ bool Text::dissolveInset(Cursor & cur)
                // restore position
                cur.pit() = min(cur.lastpit(), spit);
                cur.pos() = min(cur.lastpos(), spos);
-       } else
-               cur.forceBufferUpdate();
+       }
+
+       cur.forceBufferUpdate();
 
        // Ensure the current language is set correctly (bug 6292)
        cur.text()->setCursor(cur, cur.pit(), cur.pos());
@@ -1755,6 +1823,7 @@ bool Text::read(Lexer & lex,
        return res;
 }
 
+
 // Returns the current font and depth as a message.
 docstring Text::currentState(Cursor const & cur) const
 {
@@ -1897,11 +1966,17 @@ docstring Text::getPossibleLabel(Cursor const & cur) const
        }
 
        if (!name.empty())
-               // FIXME refstyle
-               // We should allow customization of the separator or else change it
                text = name + ':' + text;
 
-       return text;
+       // We need a unique label
+       docstring label = text;
+       int i = 1;
+       while (cur.buffer()->insetLabel(label)) {
+                       label = text + '-' + convert<docstring>(i);
+                       ++i;
+               }
+
+       return label;
 }
 
 
@@ -1923,6 +1998,18 @@ docstring Text::asString(pit_type beg, pit_type end, int options) const
 }
 
 
+void Text::forToc(docstring & os, size_t maxlen, bool shorten) const
+{
+       if (maxlen == 0)
+               maxlen = std::numeric_limits<std::size_t>::max();
+       else
+               LASSERT(maxlen >= 8, maxlen = TOC_ENTRY_LENGTH);
+       for (size_t i = 0; i != pars_.size() && os.length() < maxlen; ++i)
+               pars_[i].forToc(os, maxlen);
+       if (shorten && os.length() >= maxlen)
+               os = os.substr(0, maxlen - 3) + from_ascii("...");
+}
+
 
 void Text::charsTranspose(Cursor & cur)
 {