]> git.lyx.org Git - lyx.git/blobdiff - src/Text.cpp
\\subfloat captions are moving arguments
[lyx.git] / src / Text.cpp
index 683a8582ac24ecb68f1e4e8f4e16d7df095d4a6b..a2ae1aed8f33b772ea527dbb824c2ff9b874bc4f 100644 (file)
@@ -30,6 +30,7 @@
 #include "Cursor.h"
 #include "CutAndPaste.h"
 #include "DispatchResult.h"
+#include "Encoding.h"
 #include "ErrorList.h"
 #include "FuncRequest.h"
 #include "factory.h"
@@ -143,7 +144,7 @@ void breakParagraphConservative(BufferParams const & bparams,
        tmp.setInsetOwner(&par.inInset());
        tmp.makeSameLayout(par);
 
-       LASSERT(pos <= par.size(), /**/);
+       LASSERT(pos <= par.size(), return);
 
        if (pos < par.size()) {
                // move everything behind the break position to the new paragraph
@@ -156,7 +157,7 @@ void breakParagraphConservative(BufferParams const & bparams,
                }
                // Move over the end-of-par change information
                tmp.setChange(tmp.size(), par.lookupChange(par.size()));
-               par.setChange(par.size(), Change(bparams.trackChanges ?
+               par.setChange(par.size(), Change(bparams.track_changes ?
                                           Change::INSERTED : Change::UNCHANGED));
        }
 }
@@ -383,10 +384,10 @@ void Text::readParToken(Paragraph & par, Lexer & lex,
                        // in this case only the empty layout is allowed
                        layoutname = tclass.plainLayoutName();
                } else if (par.usePlainLayout()) {
-                       // in this case, default layout maps to empty layout 
+                       // in this case, default layout maps to empty layout
                        if (layoutname == tclass.defaultLayoutName())
                                layoutname = tclass.plainLayoutName();
-               } else { 
+               } else {
                        // otherwise, the empty layout maps to the default
                        if (layoutname == tclass.plainLayoutName())
                                layoutname = tclass.defaultLayoutName();
@@ -571,7 +572,7 @@ void Text::readParagraph(Paragraph & par, Lexer & lex,
 
        // Initialize begin_of_body_ on load; redoParagraph maintains
        par.setBeginOfBody();
-       
+
        // mark paragraph for spell checking on load
        // par.requestSpellCheck();
 }
@@ -582,11 +583,11 @@ class TextCompletionList : public CompletionList
 public:
        ///
        TextCompletionList(Cursor const & cur, WordList const * list)
-               : buffer_(cur.buffer()), pos_(0), list_(list)
+               : buffer_(cur.buffer()), list_(list)
        {}
        ///
        virtual ~TextCompletionList() {}
-       
+
        ///
        virtual bool sorted() const { return true; }
        ///
@@ -599,13 +600,11 @@ public:
        {
                return list_->word(idx);
        }
-       
+
 private:
        ///
        Buffer const * buffer_;
        ///
-       size_t pos_;
-       ///
        WordList const * list_;
 };
 
@@ -613,7 +612,7 @@ private:
 bool Text::empty() const
 {
        return pars_.empty() || (pars_.size() == 1 && pars_[0].empty()
-               // FIXME: Should we consider the labeled type as empty too? 
+               // FIXME: Should we consider the labeled type as empty too?
                && pars_[0].layout().labeltype == LABEL_NO_LABEL);
 }
 
@@ -630,10 +629,10 @@ double Text::spacing(Paragraph const & par) const
  * This breaks a paragraph at the specified position.
  * The new paragraph will:
  * - Decrease depth by one (or change layout to default layout) when
- *    keep_layout == false  
+ *    keep_layout == false
  * - keep current depth and layout when keep_layout == true
  */
-static void breakParagraph(Text & text, pit_type par_offset, pos_type pos, 
+static void breakParagraph(Text & text, pit_type par_offset, pos_type pos,
                    bool keep_layout)
 {
        BufferParams const & bparams = text.inset().buffer().params();
@@ -692,7 +691,7 @@ static void breakParagraph(Text & text, pit_type par_offset, pos_type pos,
 
        // Move over the end-of-par change information
        tmp->setChange(tmp->size(), par.lookupChange(par.size()));
-       par.setChange(par.size(), Change(bparams.trackChanges ?
+       par.setChange(par.size(), Change(bparams.track_changes ?
                                           Change::INSERTED : Change::UNCHANGED));
 
        if (pos) {
@@ -726,7 +725,7 @@ static void breakParagraph(Text & text, pit_type par_offset, pos_type pos,
 
 void Text::breakParagraph(Cursor & cur, bool inverse_logic)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
 
        Paragraph & cpar = cur.paragraph();
        pit_type cpit = cur.pit();
@@ -737,8 +736,11 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
        if (cur.lastpos() == 0 && !cpar.allowEmpty()) {
                if (changeDepthAllowed(cur, DEC_DEPTH))
                        changeDepth(cur, DEC_DEPTH);
-               else 
-                       setLayout(cur, tclass.defaultLayoutName());
+               else {
+                       docstring const & lay = cur.paragraph().usePlainLayout()
+                           ? tclass.plainLayoutName() : tclass.defaultLayoutName();
+                       setLayout(cur, lay);
+               }
                return;
        }
 
@@ -747,10 +749,10 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
        // Always break behind a space
        // It is better to erase the space (Dekel)
        if (cur.pos() != cur.lastpos() && cpar.isLineSeparator(cur.pos()))
-               cpar.eraseChar(cur.pos(), cur.buffer()->params().trackChanges);
+               cpar.eraseChar(cur.pos(), cur.buffer()->params().track_changes);
 
        // What should the layout for the new paragraph be?
-       bool keep_layout = layout.isEnvironment() 
+       bool keep_layout = layout.isEnvironment()
                || (layout.isParagraph() && layout.parbreak_is_newline);
        if (inverse_logic)
                keep_layout = !keep_layout;
@@ -782,7 +784,7 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
        }
 
        while (!pars_[next_par].empty() && pars_[next_par].isNewline(0)) {
-               if (!pars_[next_par].eraseChar(0, cur.buffer()->params().trackChanges))
+               if (!pars_[next_par].eraseChar(0, cur.buffer()->params().track_changes))
                        break; // the character couldn't be deleted physically due to change tracking
        }
 
@@ -829,11 +831,11 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str,
                } else if (*cit == '\t') {
                        if (!par.isFreeSpacing()) {
                                // tabs are like spaces here
-                               par.insertChar(pos, ' ', font, bparams.trackChanges);
+                               par.insertChar(pos, ' ', font, bparams.track_changes);
                                ++pos;
                                space_inserted = true;
                        } else {
-                               par.insertChar(pos, *cit, font, bparams.trackChanges);
+                               par.insertChar(pos, *cit, font, bparams.track_changes);
                                ++pos;
                                space_inserted = true;
                        }
@@ -842,7 +844,7 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str,
                        continue;
                } else {
                        // just insert the character
-                       par.insertChar(pos, *cit, font, bparams.trackChanges);
+                       par.insertChar(pos, *cit, font, bparams.track_changes);
                        ++pos;
                        space_inserted = (*cit == ' ');
                }
@@ -883,7 +885,7 @@ void Text::insertStringAsParagraphs(Cursor & cur, docstring const & str,
 // same Paragraph one to the right and make a rebreak
 void Text::insertChar(Cursor & cur, char_type c)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
 
        cur.recordUndo(INSERT_UNDO);
 
@@ -919,6 +921,7 @@ void Text::insertChar(Cursor & cur, char_type c)
                                if (contains(number_unary_operators, c) &&
                                    (cur.pos() == 1
                                     || par.isSeparator(cur.pos() - 2)
+                                    || par.isEnvSeparator(cur.pos() - 2)
                                     || par.isNewline(cur.pos() - 2))
                                  ) {
                                        setCharFont(pit, cur.pos() - 1, cur.current_font,
@@ -934,40 +937,40 @@ void Text::insertChar(Cursor & cur, char_type c)
        }
 
        // In Bidi text, we want spaces to be treated in a special way: spaces
-       // which are between words in different languages should get the 
-       // paragraph's language; otherwise, spaces should keep the language 
+       // which are between words in different languages should get the
+       // paragraph's language; otherwise, spaces should keep the language
        // they were originally typed in. This is only in effect while typing;
        // after the text is already typed in, the user can always go back and
        // explicitly set the language of a space as desired. But 99.9% of the
        // time, what we're doing here is what the user actually meant.
-       // 
+       //
        // The following cases are the ones in which the language of the space
        // should be changed to match that of the containing paragraph. In the
-       // depictions, lowercase is LTR, uppercase is RTL, underscore (_) 
+       // depictions, lowercase is LTR, uppercase is RTL, underscore (_)
        // represents a space, pipe (|) represents the cursor position (so the
        // character before it is the one just typed in). The different cases
        // are depicted logically (not visually), from left to right:
-       // 
+       //
        // 1. A_a|
        // 2. a_A|
        //
        // Theoretically, there are other situations that we should, perhaps, deal
-       // with (e.g.: a|_A, A|_a). In practice, though, there really isn't any 
+       // with (e.g.: a|_A, A|_a). In practice, though, there really isn't any
        // point (to understand why, just try to create this situation...).
 
        if ((cur.pos() >= 2) && (par.isLineSeparator(cur.pos() - 1))) {
-               // get font in front and behind the space in question. But do NOT 
+               // get font in front and behind the space in question. But do NOT
                // use getFont(cur.pos()) because the character c is not inserted yet
                Font const pre_space_font  = tm.displayFont(cur.pit(), cur.pos() - 2);
                Font const & post_space_font = cur.real_current_font;
                bool pre_space_rtl  = pre_space_font.isVisibleRightToLeft();
                bool post_space_rtl = post_space_font.isVisibleRightToLeft();
-               
+
                if (pre_space_rtl != post_space_rtl) {
-                       // Set the space's language to match the language of the 
+                       // Set the space's language to match the language of the
                        // adjacent character whose direction is the paragraph's
                        // direction; don't touch other properties of the font
-                       Language const * lang = 
+                       Language const * lang =
                                (pre_space_rtl == par.isRTL(buffer.params())) ?
                                pre_space_font.language() : post_space_font.language();
 
@@ -976,7 +979,7 @@ void Text::insertChar(Cursor & cur, char_type c)
                        par.setFont(cur.pos() - 1, space_font);
                }
        }
-       
+
        // Next check, if there will be two blanks together or a blank at
        // the beginning of a paragraph.
        // I decided to handle blanks like normal characters, the main
@@ -992,6 +995,7 @@ void Text::insertChar(Cursor & cur, char_type c)
                                        "beginning of a paragraph. Please read the Tutorial."));
                        return;
                }
+               // LASSERT: Is it safe to continue here?
                LASSERT(cur.pos() > 0, /**/);
                if ((par.isLineSeparator(cur.pos() - 1) || par.isNewline(cur.pos() - 1))
                                && !par.isDeleted(cur.pos() - 1)) {
@@ -1002,8 +1006,21 @@ void Text::insertChar(Cursor & cur, char_type c)
                }
        }
 
+       // Prevent to insert uncodable characters in verbatim and ERT
+       // (workaround for bug 9012)
+       // Don't do it for listings inset, since InsetListings::latex() tries
+       // to switch to a usable encoding which works in many cases (bug 9102).
+       if (cur.paragraph().isPassThru() && owner_->lyxCode() != LISTINGS_CODE &&
+           cur.current_font.language()) {
+               Encoding const * e = cur.current_font.language()->encoding();
+               if (!e->encodable(c)) {
+                       cur.message(_("Character is uncodable in verbatim paragraphs."));
+                       return;
+               }
+       }
+
        par.insertChar(cur.pos(), c, cur.current_font,
-               cur.buffer()->params().trackChanges);
+               cur.buffer()->params().track_changes);
        cur.checkBufferStructure();
 
 //             cur.screenUpdateFlags(Update::Force);
@@ -1032,7 +1049,7 @@ void Text::charInserted(Cursor & cur)
            && !par.isWordSeparator(cur.pos() - 2)
            && par.isWordSeparator(cur.pos() - 1)) {
                // get the word in front of cursor
-               LASSERT(this == cur.text(), /**/);
+               LBUFERR(this == cur.text());
                cur.paragraph().updateWords();
        }
 }
@@ -1043,7 +1060,7 @@ void Text::charInserted(Cursor & cur)
 
 bool Text::cursorForwardOneWord(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
 
        pos_type const lastpos = cur.lastpos();
        pit_type pit = cur.pit();
@@ -1058,7 +1075,7 @@ bool Text::cursorForwardOneWord(Cursor & cur)
                        return false;
        }
 
-       if (lyxrc.mac_like_word_movement) {
+       if (lyxrc.mac_like_cursor_movement) {
                // Skip through trailing punctuation and spaces.
                while (pos != lastpos && (par.isChar(pos) || par.isSpace(pos)))
                         ++pos;
@@ -1069,7 +1086,7 @@ bool Text::cursorForwardOneWord(Cursor & cur)
                else while (pos != lastpos && !par.isWordSeparator(pos))
                             ++pos;
        } else {
-               LASSERT(pos < lastpos, /**/); // see above
+               LASSERT(pos < lastpos, return false); // see above
                if (!par.isWordSeparator(pos))
                        while (pos != lastpos && !par.isWordSeparator(pos))
                                ++pos;
@@ -1081,7 +1098,7 @@ bool Text::cursorForwardOneWord(Cursor & cur)
 
                // Skip over white space
                while (pos != lastpos && par.isSpace(pos))
-                            ++pos;             
+                            ++pos;
        }
 
        return setCursor(cur, pit, pos);
@@ -1090,7 +1107,7 @@ bool Text::cursorForwardOneWord(Cursor & cur)
 
 bool Text::cursorBackwardOneWord(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
 
        pit_type pit = cur.pit();
        pos_type pos = cur.pos();
@@ -1100,7 +1117,7 @@ bool Text::cursorBackwardOneWord(Cursor & cur)
        if (pos == 0 && pit != 0)
                return setCursor(cur, pit - 1, getPar(pit - 1).size());
 
-       if (lyxrc.mac_like_word_movement) {
+       if (lyxrc.mac_like_cursor_movement) {
                // Skip through punctuation and spaces.
                while (pos != 0 && (par.isChar(pos - 1) || par.isSpace(pos - 1)))
                        --pos;
@@ -1131,7 +1148,7 @@ bool Text::cursorBackwardOneWord(Cursor & cur)
 
 bool Text::cursorVisLeftOneWord(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
 
        pos_type left_pos, right_pos;
        bool left_is_letter, right_is_letter;
@@ -1143,9 +1160,9 @@ bool Text::cursorVisLeftOneWord(Cursor & cur)
 
                // collect some information about current cursor position
                temp_cur.getSurroundingPos(left_pos, right_pos);
-               left_is_letter = 
+               left_is_letter =
                        (left_pos > -1 ? !temp_cur.paragraph().isWordSeparator(left_pos) : false);
-               right_is_letter = 
+               right_is_letter =
                        (right_pos > -1 ? !temp_cur.paragraph().isWordSeparator(right_pos) : false);
 
                // if we're not at a letter/non-letter boundary, continue moving
@@ -1161,14 +1178,14 @@ bool Text::cursorVisLeftOneWord(Cursor & cur)
                        break;
        }
 
-       return setCursor(cur, temp_cur.pit(), temp_cur.pos(), 
+       return setCursor(cur, temp_cur.pit(), temp_cur.pos(),
                                         true, temp_cur.boundary());
 }
 
 
 bool Text::cursorVisRightOneWord(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
 
        pos_type left_pos, right_pos;
        bool left_is_letter, right_is_letter;
@@ -1180,9 +1197,9 @@ bool Text::cursorVisRightOneWord(Cursor & cur)
 
                // collect some information about current cursor position
                temp_cur.getSurroundingPos(left_pos, right_pos);
-               left_is_letter = 
+               left_is_letter =
                        (left_pos > -1 ? !temp_cur.paragraph().isWordSeparator(left_pos) : false);
-               right_is_letter = 
+               right_is_letter =
                        (right_pos > -1 ? !temp_cur.paragraph().isWordSeparator(right_pos) : false);
 
                // if we're not at a letter/non-letter boundary, continue moving
@@ -1192,22 +1209,22 @@ bool Text::cursorVisRightOneWord(Cursor & cur)
                // we should stop when we have an LTR word on our right or an RTL word
                // on our left
                if ((left_is_letter && temp_cur.paragraph().getFontSettings(
-                               temp_cur.buffer()->params(), 
+                               temp_cur.buffer()->params(),
                                left_pos).isRightToLeft())
                        || (right_is_letter && !temp_cur.paragraph().getFontSettings(
-                               temp_cur.buffer()->params(), 
+                               temp_cur.buffer()->params(),
                                right_pos).isRightToLeft()))
                        break;
        }
 
-       return setCursor(cur, temp_cur.pit(), temp_cur.pos(), 
+       return setCursor(cur, temp_cur.pit(), temp_cur.pos(),
                                         true, temp_cur.boundary());
 }
 
 
 void Text::selectWord(Cursor & cur, word_location loc)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        CursorSlice from = cur.top();
        CursorSlice to = cur.top();
        getWord(from, to, loc);
@@ -1225,14 +1242,14 @@ void Text::selectWord(Cursor & cur, word_location loc)
 
 void Text::selectAll(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        if (cur.lastpos() == 0 && cur.lastpit() == 0)
                return;
        // If the cursor is at the beginning, make sure the cursor ends there
        if (cur.pit() == 0 && cur.pos() == 0) {
                setCursor(cur, cur.lastpit(), getPar(cur.lastpit()).size());
                cur.resetAnchor();
-               setCursor(cur, 0, 0);           
+               setCursor(cur, 0, 0);
        } else {
                setCursor(cur, 0, 0);
                cur.resetAnchor();
@@ -1246,7 +1263,7 @@ void Text::selectAll(Cursor & cur)
 // selection is currently set
 bool Text::selectWordWhenUnderCursor(Cursor & cur, word_location loc)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        if (cur.selection())
                return false;
        selectWord(cur, loc);
@@ -1256,11 +1273,10 @@ bool Text::selectWordWhenUnderCursor(Cursor & cur, word_location loc)
 
 void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
 
        if (!cur.selection()) {
-               bool const changed = cur.paragraph().isChanged(cur.pos());
-               if (!(changed && findNextChange(&cur.bv())))
+               if (!selectChange(cur))
                        return;
        }
 
@@ -1276,7 +1292,6 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
        bool endsBeforeEndOfPar = (endPos < pars_[endPit].size());
 
        // first, accept/reject changes within each individual paragraph (do not consider end-of-par)
-
        for (pit_type pit = begPit; pit <= endPit; ++pit) {
                pos_type parSize = pars_[pit].size();
 
@@ -1295,11 +1310,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 {
@@ -1352,10 +1367,7 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
        }
 
        // finally, invoke the DEPM
-
-       deleteEmptyParagraphMechanism(begPit, endPit, cur.buffer()->params().trackChanges);
-
-       //
+       deleteEmptyParagraphMechanism(begPit, endPit, cur.buffer()->params().track_changes);
 
        cur.finishUndo();
        cur.clearSelection();
@@ -1369,7 +1381,7 @@ void Text::acceptChanges()
 {
        BufferParams const & bparams = owner_->buffer().params();
        lyx::acceptChanges(pars_, bparams);
-       deleteEmptyParagraphMechanism(0, pars_.size() - 1, bparams.trackChanges);
+       deleteEmptyParagraphMechanism(0, pars_.size() - 1, bparams.track_changes);
 }
 
 
@@ -1405,13 +1417,13 @@ void Text::rejectChanges()
        }
 
        // finally, invoke the DEPM
-       deleteEmptyParagraphMechanism(0, pars_size - 1, bparams.trackChanges);
+       deleteEmptyParagraphMechanism(0, pars_size - 1, bparams.track_changes);
 }
 
 
 void Text::deleteWordForward(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        if (cur.lastpos() == 0)
                cursorForward(cur);
        else {
@@ -1427,7 +1439,7 @@ void Text::deleteWordForward(Cursor & cur)
 
 void Text::deleteWordBackward(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        if (cur.lastpos() == 0)
                cursorBackward(cur);
        else {
@@ -1444,7 +1456,7 @@ void Text::deleteWordBackward(Cursor & cur)
 // Kill to end of line.
 void Text::changeCase(Cursor & cur, TextCase action)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        CursorSlice from;
        CursorSlice to;
 
@@ -1516,7 +1528,7 @@ bool Text::handleBibitems(Cursor & cur)
                setCursorIntern(cur, prevcur.pit(), prevcur.pos());
                cur.screenUpdateFlags(Update::Force);
                return true;
-       } 
+       }
 
        // otherwise reset to default
        cur.paragraph().setPlainOrDefaultLayout(bufparams.documentClass());
@@ -1535,7 +1547,7 @@ bool Text::erase(Cursor & cur)
                // any paragraphs
                cur.recordUndo(DELETE_UNDO);
                bool const was_inset = cur.paragraph().isInset(cur.pos());
-               if(!par.eraseChar(cur.pos(), cur.buffer()->params().trackChanges))
+               if(!par.eraseChar(cur.pos(), cur.buffer()->params().track_changes))
                        // the character has been logically deleted only => skip it
                        cur.top().forwardPos();
 
@@ -1548,7 +1560,7 @@ bool Text::erase(Cursor & cur)
                if (cur.pit() == cur.lastpit())
                        return dissolveInset(cur);
 
-               if (!par.isMergedOnEndOfParDeletion(cur.buffer()->params().trackChanges)) {
+               if (!par.isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) {
                        par.setChange(cur.pos(), Change(Change::DELETED));
                        cur.forwardPos();
                        needsUpdate = true;
@@ -1573,7 +1585,7 @@ bool Text::erase(Cursor & cur)
 
 bool Text::backspacePos0(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        if (cur.pit() == 0)
                return false;
 
@@ -1626,17 +1638,19 @@ bool Text::backspacePos0(Cursor & cur)
 
 bool Text::backspace(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        bool needsUpdate = false;
        if (cur.pos() == 0) {
                if (cur.pit() == 0)
                        return dissolveInset(cur);
 
-               Paragraph & prev_par = pars_[cur.pit() - 1];
+               Cursor prev_cur = cur;
+               --prev_cur.pit();
 
-               if (!prev_par.isMergedOnEndOfParDeletion(cur.buffer()->params().trackChanges)) {
-                       prev_par.setChange(prev_par.size(), Change(Change::DELETED));
-                       setCursorIntern(cur, cur.pit() - 1, prev_par.size());
+               if (!prev_cur.paragraph().isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) {
+                       cur.recordUndo(ATOMIC_UNDO, prev_cur.pit(), prev_cur.pit());
+                       prev_cur.paragraph().setChange(prev_cur.lastpos(), Change(Change::DELETED));
+                       setCursorIntern(cur, prev_cur.pit(), prev_cur.lastpos());
                        return true;
                }
                // The cursor is at the beginning of a paragraph, so
@@ -1654,7 +1668,7 @@ bool Text::backspace(Cursor & cur)
                setCursorIntern(cur, cur.pit(), cur.pos() - 1,
                                false, cur.boundary());
                bool const was_inset = cur.paragraph().isInset(cur.pos());
-               cur.paragraph().eraseChar(cur.pos(), cur.buffer()->params().trackChanges);
+               cur.paragraph().eraseChar(cur.pos(), cur.buffer()->params().track_changes);
                if (was_inset)
                        cur.forceBufferUpdate();
                else
@@ -1696,7 +1710,7 @@ bool Text::dissolveInset(Cursor & cur)
                spos += cur.pos();
        spit += cur.pit();
        Buffer & b = *cur.buffer();
-       cur.paragraph().eraseChar(cur.pos(), b.params().trackChanges);
+       cur.paragraph().eraseChar(cur.pos(), b.params().track_changes);
 
        if (!plist.empty()) {
                // see bug 7319
@@ -1756,7 +1770,7 @@ void Text::write(ostream & os) const
 }
 
 
-bool Text::read(Lexer & lex, 
+bool Text::read(Lexer & lex,
                ErrorList & errorList, InsetText * insetPtr)
 {
        Buffer const & buf = owner_->buffer();
@@ -1813,12 +1827,12 @@ bool Text::read(Lexer & lex,
                Paragraph par;
                par.setInsetOwner(insetPtr);
                par.params().depth(depth);
-               par.setFont(0, Font(inherit_font, 
+               par.setFont(0, Font(inherit_font,
                                    buf.params().language));
                par.setPlainOrDefaultLayout(buf.params().documentClass());
                pars_.push_back(par);
        }
-       
+
        return res;
 }
 
@@ -1826,12 +1840,12 @@ bool Text::read(Lexer & lex,
 // Returns the current font and depth as a message.
 docstring Text::currentState(Cursor const & cur) const
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
        Buffer & buf = *cur.buffer();
        Paragraph const & par = cur.paragraph();
        odocstringstream os;
 
-       if (buf.params().trackChanges)
+       if (buf.params().track_changes)
                os << _("[Change Tracking] ");
 
        Change change = par.lookupChange(cur.pos());
@@ -1925,7 +1939,7 @@ docstring Text::getPossibleLabel(Cursor const & cur) const
                        text += '-';
                text += head;
        }
-       
+
        // Make sure it isn't too long
        unsigned int const max_label_length = 32;
        if (text.size() > max_label_length)
@@ -1948,7 +1962,7 @@ docstring Text::getPossibleLabel(Cursor const & cur) const
        // For captions, we just take the caption type
        Inset * caption_inset = cur.innerInsetOfType(CAPTION_CODE);
        if (caption_inset) {
-               string const & ftype = static_cast<InsetCaption *>(caption_inset)->type();
+               string const & ftype = static_cast<InsetCaption *>(caption_inset)->floattype();
                FloatList const & fl = cur.buffer()->params().documentClass().floats();
                if (fl.typeExist(ftype)) {
                        Floating const & flt = fl.getType(ftype);
@@ -1997,14 +2011,14 @@ docstring Text::asString(pit_type beg, pit_type end, int options) const
 }
 
 
-void Text::forToc(docstring & os, size_t maxlen, bool shorten) const
+void Text::forOutliner(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);
+               pars_[i].forOutliner(os, maxlen);
        if (shorten && os.length() >= maxlen)
                os = os.substr(0, maxlen - 3) + from_ascii("...");
 }
@@ -2012,7 +2026,7 @@ void Text::forToc(docstring & os, size_t maxlen, bool shorten) const
 
 void Text::charsTranspose(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LBUFERR(this == cur.text());
 
        pos_type pos = cur.pos();
 
@@ -2052,7 +2066,7 @@ void Text::charsTranspose(Cursor & cur)
 
        // And finally, we are ready to perform the transposition.
        // Track the changes if Change Tracking is enabled.
-       bool const trackChanges = cur.buffer()->params().trackChanges;
+       bool const trackChanges = cur.buffer()->params().track_changes;
 
        cur.recordUndo();
 
@@ -2088,7 +2102,7 @@ docstring Text::previousWord(CursorSlice const & sl) const
        getWord(from, to, PREVIOUS_WORD);
        if (sl == from || to == from)
                return docstring();
-       
+
        Paragraph const & par = sl.paragraph();
        return par.asString(from.pos(), to.pos());
 }
@@ -2105,22 +2119,22 @@ bool Text::completionSupported(Cursor const & cur) const
 
 CompletionList const * Text::createCompletionList(Cursor const & cur) const
 {
-       WordList const * list = theWordList(*cur.getFont().language());
+       WordList const * list = theWordList(cur.getFont().language()->lang());
        return new TextCompletionList(cur, list);
 }
 
 
 bool Text::insertCompletion(Cursor & cur, docstring const & s, bool /*finished*/)
-{      
-       LASSERT(cur.bv().cursor() == cur, /**/);
+{
+       LBUFERR(cur.bv().cursor() == cur);
        cur.insert(s);
        cur.bv().cursor() = cur;
        if (!(cur.result().screenUpdate() & Update::Force))
                cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar);
        return true;
 }
-       
-       
+
+
 docstring Text::completionPrefix(Cursor const & cur) const
 {
        return previousWord(cur.top());