]> git.lyx.org Git - lyx.git/blobdiff - src/text2.C
clean up a bit
[lyx.git] / src / text2.C
index bec3b8529fa38f46f456b4e3c8c6fb4c4a6fa862..16c056c7b6d603483af90cf51ad2ec0044176fed 100644 (file)
 #include "lyxtext.h"
 #include "LString.h"
 #include "paragraph.h"
-#include "lyxtextclasslist.h"
-#include "LyXView.h"
+#include "frontends/LyXView.h"
 #include "undo_funcs.h"
 #include "buffer.h"
 #include "bufferparams.h"
 #include "gettext.h"
 #include "BufferView.h"
-#include "LyXView.h"
 #include "CutAndPaste.h"
-#include "Painter.h"
-#include "font.h"
+#include "frontends/Painter.h"
+#include "frontends/font_metrics.h"
 #include "debug.h"
 #include "lyxrc.h"
 #include "lyxrow.h"
 #include "FloatList.h"
 #include "language.h"
 #include "ParagraphParameters.h"
+#include "counters.h"
 
 #include "insets/inseterror.h"
 #include "insets/insetbib.h"
 #include "insets/insetspecialchar.h"
 #include "insets/insettext.h"
 #include "insets/insetfloat.h"
+#include "insets/insetwrap.h"
 
 #include "support/LAssert.h"
 #include "support/textutils.h"
 #include "support/lstrings.h"
 
+#include "BoostFormat.h"
+
 using std::vector;
 using std::copy;
-using std::find;
 using std::endl;
 using std::find;
 using std::pair;
@@ -55,7 +56,7 @@ using lyx::pos_type;
 
 
 LyXText::LyXText(BufferView * bv)
-       : number_of_rows(0), height(0), width(0), first_y(0),
+       : height(0), width(0), first_y(0),
          bv_owner(bv), inset_owner(0), the_locking_inset(0),
          need_break_row(0), refresh_y(0), refresh_row(0),
          status_(LyXText::UNCHANGED), firstrow(0), lastrow(0)
@@ -63,7 +64,7 @@ LyXText::LyXText(BufferView * bv)
 
 
 LyXText::LyXText(InsetText * inset)
-       :  number_of_rows(0),  height(0), width(0), first_y(0),
+       :  height(0), width(0), first_y(0),
           bv_owner(0), inset_owner(inset), the_locking_inset(0),
           need_break_row(0), refresh_y(0), refresh_row(0),
           status_(LyXText::UNCHANGED), firstrow(0), lastrow(0)
@@ -86,7 +87,7 @@ void LyXText::init(BufferView * bview, bool reinit)
                need_break_row = 0;
                width = height = 0;
                copylayouttype.erase();
-               number_of_rows = first_y = refresh_y = 0;
+               first_y = refresh_y = 0;
                status_ = LyXText::UNCHANGED;
        } else if (firstrow)
                return;
@@ -100,6 +101,8 @@ void LyXText::init(BufferView * bview, bool reinit)
        }
        setCursorIntern(bview, firstrow->par(), 0);
        selection.cursor = cursor;
+
+       updateCounters(bview);
 }
 
 
@@ -121,6 +124,7 @@ LyXFont const realizeFont(LyXFont const & font,
                          Buffer const * buf,
                          Paragraph * par)
 {
+       LyXTextClass const & tclass = buf->params.getLyXTextClass();
        LyXFont tmpfont(font);
        Paragraph::depth_type par_depth = par->getDepth();
 
@@ -128,25 +132,12 @@ LyXFont const realizeFont(LyXFont const & font,
        while (par && par_depth && !tmpfont.resolved()) {
                par = par->outerHook();
                if (par) {
-#ifndef INHERIT_LANGUAGE
-                       tmpfont.realize(textclasslist[buf->params.textclass][
-                                             par->layout()].font);
-#else
-                       tmpfont.realize(textclasslist.
-                                       Style(buf->params.textclass,
-                                             par->layout()).font,
-                                       buf->params.language);
-#endif
+                       tmpfont.realize(par->layout()->font);
                        par_depth = par->getDepth();
                }
        }
 
-#ifndef INHERIT_LANGUAGE
-       tmpfont.realize(textclasslist[buf->params.textclass].defaultfont());
-#else
-       tmpfont.realize(textclasslist[buf->params.textclass].defaultfont(),
-                       buf->params.language);
-#endif
+       tmpfont.realize(tclass.defaultfont());
 
        return tmpfont;
 }
@@ -166,32 +157,22 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par,
 {
        lyx::Assert(pos >= 0);
 
-       LyXLayout const & layout =
-               textclasslist[buf->params.textclass][par->layout()];
+       LyXLayout_ptr const & layout = par->layout();
 
-       Paragraph::depth_type par_depth = par->getDepth();
        // We specialize the 95% common case:
-       if (!par_depth) {
-               if (layout.labeltype == LABEL_MANUAL
+       if (!par->getDepth()) {
+               if (layout->labeltype == LABEL_MANUAL
                    && pos < beginningOfMainBody(buf, par)) {
                        // 1% goes here
                        LyXFont f = par->getFontSettings(buf->params, pos);
                        if (par->inInset())
                                par->inInset()->getDrawFont(f);
-#ifndef INHERIT_LANGUAGE
-                       return f.realize(layout.reslabelfont);
-#else
-                       return f.realize(layout.reslabelfont, buf->params.language);
-#endif
+                       return f.realize(layout->reslabelfont);
                } else {
                        LyXFont f = par->getFontSettings(buf->params, pos);
                        if (par->inInset())
                                par->inInset()->getDrawFont(f);
-#ifndef INHERIT_LANGUAGE
-                       return f.realize(layout.resfont);
-#else
-                       return f.realize(layout.resfont, buf->params.language);
-#endif
+                       return f.realize(layout->resfont);
                }
        }
 
@@ -201,18 +182,15 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par,
 
        if (pos < beginningOfMainBody(buf, par)) {
                // 1% goes here
-               layoutfont = layout.labelfont;
+               layoutfont = layout->labelfont;
        } else {
                // 99% goes here
-               layoutfont = layout.font;
+               layoutfont = layout->font;
        }
 
        LyXFont tmpfont = par->getFontSettings(buf->params, pos);
-#ifndef INHERIT_LANGUAGE
        tmpfont.realize(layoutfont);
-#else
-       tmpfont.realize(layoutfont, buf->params.language);
-#endif
+
        if (par->inInset())
                par->inInset()->getDrawFont(tmpfont);
 
@@ -222,31 +200,25 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par,
 
 LyXFont const LyXText::getLayoutFont(Buffer const * buf, Paragraph * par) const
 {
-       LyXLayout const & layout =
-               textclasslist[buf->params.textclass][par->layout()];
-
-       Paragraph::depth_type par_depth = par->getDepth();
+       LyXLayout_ptr const & layout = par->layout();
 
-       if (!par_depth) {
-               return layout.resfont;
+       if (!par->getDepth()) {
+               return layout->resfont;
        }
 
-       return realizeFont(layout.font, buf, par);
+       return realizeFont(layout->font, buf, par);
 }
 
 
 LyXFont const LyXText::getLabelFont(Buffer const * buf, Paragraph * par) const
 {
-       LyXLayout const & layout =
-               textclasslist[buf->params.textclass][par->layout()];
-
-       Paragraph::depth_type par_depth = par->getDepth();
+       LyXLayout_ptr const & layout = par->layout();
 
-       if (!par_depth) {
-               return layout.reslabelfont;
+       if (!par->getDepth()) {
+               return layout->reslabelfont;
        }
 
-       return realizeFont(layout.labelfont, buf, par);
+       return realizeFont(layout->labelfont, buf, par);
 }
 
 
@@ -277,16 +249,16 @@ void LyXText::setCharFont(Buffer const * buf, Paragraph * par,
 {
        LyXFont font(fnt);
 
-       LyXTextClass const & tclass = textclasslist[buf->params.textclass];
-       LyXLayout const & layout = tclass[par->layout()];
+       LyXTextClass const & tclass = buf->params.getLyXTextClass();
+       LyXLayout_ptr const & layout = par->layout();
 
        // Get concrete layout font to reduce against
        LyXFont layoutfont;
 
        if (pos < beginningOfMainBody(buf, par))
-               layoutfont = layout.labelfont;
+               layoutfont = layout->labelfont;
        else
-               layoutfont = layout.font;
+               layoutfont = layout->font;
 
        // Realize against environment font information
        if (par->getDepth()) {
@@ -294,22 +266,11 @@ void LyXText::setCharFont(Buffer const * buf, Paragraph * par,
                while (!layoutfont.resolved() && tp && tp->getDepth()) {
                        tp = tp->outerHook();
                        if (tp)
-#ifndef INHERIT_LANGUAGE
-                               layoutfont.realize(tclass[tp->layout()].font);
-#else
-                               layoutfont.realize(textclasslist.
-                                                  Style(buf->params.textclass,
-                                                        tp->layout()).font,
-                                                  buf->params.language);
-#endif
+                               layoutfont.realize(tp->layout()->font);
                }
        }
 
-#ifndef INHERIT_LANGUAGE
        layoutfont.realize(tclass.defaultfont());
-#else
-       layoutfont.realize(tclass.defaultfont(), buf->params.language);
-#endif
 
        // Now, reduce font against full layout font
        font.reduce(layoutfont);
@@ -346,7 +307,6 @@ void LyXText::insertRow(Row * row, Paragraph * par,
 
        if (row == lastrow)
                lastrow = tmprow;
-       ++number_of_rows;
 }
 
 
@@ -374,7 +334,6 @@ void LyXText::removeRow(Row * row) const
        height -= row->height(); // the text becomes smaller
 
        delete row;
-       --number_of_rows;       // one row less
 }
 
 
@@ -397,10 +356,8 @@ void LyXText::removeParagraph(Row * row) const
 void LyXText::insertParagraph(BufferView * bview, Paragraph * par,
                              Row * row) const
 {
-       insertRow(row, par, 0);            /* insert a new row, starting
-                                           * at postition 0 */
-
-       setCounter(bview->buffer(), par);  // set the counters
+       // insert a new row, starting at position 0
+       insertRow(row, par, 0);
 
        // and now append the whole paragraph behind the new row
        if (!row) {
@@ -436,6 +393,7 @@ void LyXText::toggleInset(BufferView * bview)
                    && inset_owner->owner()->isOpen()) {
                        bview->unlockInset(static_cast<UpdatableInset *>(inset_owner->owner()));
                        inset_owner->owner()->close(bview);
+                       bview->getLyXText()->cursorRight(bview);
                }
                return;
        }
@@ -461,15 +419,14 @@ void LyXText::toggleInset(BufferView * bview)
 void LyXText::makeFontEntriesLayoutSpecific(Buffer const * buf,
                                            Paragraph * par)
 {
-       LyXLayout const & layout =
-               textclasslist[buf->params.textclass][par->layout()];
+       LyXLayout_ptr const & layout = par->layout();
 
        LyXFont layoutfont;
        for (pos_type pos = 0; pos < par->size(); ++pos) {
                if (pos < beginningOfMainBody(buf, par))
-                       layoutfont = layout.labelfont;
+                       layoutfont = layout->labelfont;
                else
-                       layoutfont = layout.font;
+                       layoutfont = layout->font;
 
                LyXFont tmpfont = par->getFontSettings(buf->params, pos);
                tmpfont.reduce(layoutfont);
@@ -503,22 +460,22 @@ Paragraph * LyXText::setLayout(BufferView * bview,
        Paragraph * par = sstart_cur.par();
        Paragraph * epar = send_cur.par()->next();
 
-       LyXLayout const & lyxlayout =
-               textclasslist[bview->buffer()->params.textclass][layout];
+       LyXLayout_ptr const & lyxlayout =
+               bview->buffer()->params.getLyXTextClass()[layout];
 
        do {
-               par->applyLayout(layout);
+               par->applyLayout(lyxlayout);
                makeFontEntriesLayoutSpecific(bview->buffer(), par);
                Paragraph * fppar = par;
-               fppar->params().spaceTop(lyxlayout.fill_top ?
+               fppar->params().spaceTop(lyxlayout->fill_top ?
                                         VSpace(VSpace::VFILL)
                                         : VSpace(VSpace::NONE));
-               fppar->params().spaceBottom(lyxlayout.fill_bottom ?
+               fppar->params().spaceBottom(lyxlayout->fill_bottom ?
                                            VSpace(VSpace::VFILL)
                                            : VSpace(VSpace::NONE));
-               if (lyxlayout.margintype == MARGIN_MANUAL)
-                       par->setLabelWidthString(lyxlayout.labelstring());
-               if (lyxlayout.labeltype != LABEL_BIBLIO
+               if (lyxlayout->margintype == MARGIN_MANUAL)
+                       par->setLabelWidthString(lyxlayout->labelstring());
+               if (lyxlayout->labeltype != LABEL_BIBLIO
                    && fppar->bibkey) {
                        delete fppar->bibkey;
                        fppar->bibkey = 0;
@@ -552,7 +509,7 @@ void LyXText::setLayout(BufferView * bview, string const & layout)
                  selection.start.pos(), false);
        selection.cursor = cursor;
        setCursor(bview, selection.end.par(), selection.end.pos(), false);
-       updateCounters(bview, cursor.row());
+       updateCounters(bview);
        clearSelection();
        setSelection(bview);
        setCursor(bview, tmpcursor.par(), tmpcursor.pos(), true);
@@ -592,21 +549,15 @@ void  LyXText::incDepth(BufferView * bview)
        // and sel_end cursor
        cursor = selection.start;
 
-       bool anything_changed = false;
-
-       LyXTextClass const & tclass =
-               textclasslist[bview->buffer()->params.textclass];
-
        while (true) {
                // NOTE: you can't change the depth of a bibliography entry
-               if (tclass[cursor.par()->layout()].labeltype != LABEL_BIBLIO) {
+               if (cursor.par()->layout()->labeltype != LABEL_BIBLIO) {
                        Paragraph * prev = cursor.par()->previous();
 
                        if (prev) {
                                if (cursor.par()->getDepth()
-                                   < prev->getMaxDepthAfter(bview->buffer())){
+                                   < prev->getMaxDepthAfter()) {
                                        cursor.par()->params().depth(cursor.par()->getDepth() + 1);
-                                       anything_changed = true;
                                }
                        }
                }
@@ -615,16 +566,6 @@ void  LyXText::incDepth(BufferView * bview)
                cursor.par(cursor.par()->next());
        }
 
-       // if nothing changed set all depth to 0
-       if (!anything_changed) {
-               cursor = selection.start;
-               while (cursor.par() != selection.end.par()) {
-                       cursor.par()->params().depth(0);
-                       cursor.par(cursor.par()->next());
-               }
-               cursor.par()->params().depth(0);
-       }
-
        redoParagraphs(bview, selection.start, endpar);
 
        // we have to reset the selection, because the
@@ -632,7 +573,7 @@ void  LyXText::incDepth(BufferView * bview)
        setCursor(bview, selection.start.par(), selection.start.pos());
        selection.cursor = cursor;
        setCursor(bview, selection.end.par(), selection.end.pos());
-       updateCounters(bview, cursor.row());
+       updateCounters(bview);
        clearSelection();
        setSelection(bview);
        setCursor(bview, tmpcursor.par(), tmpcursor.pos());
@@ -689,7 +630,7 @@ void  LyXText::decDepth(BufferView * bview)
                  selection.start.pos());
        selection.cursor = cursor;
        setCursor(bview, selection.end.par(), selection.end.pos());
-       updateCounters(bview, cursor.row());
+       updateCounters(bview);
        clearSelection();
        setSelection(bview);
        setCursor(bview, tmpcursor.par(), tmpcursor.pos());
@@ -720,12 +661,8 @@ void LyXText::setFont(BufferView * bview, LyXFont const & font, bool toggleall)
                current_font = real_current_font;
                current_font.reduce(layoutfont);
                // And resolve it completely
-#ifndef INHERIT_LANGUAGE
                real_current_font.realize(layoutfont);
-#else
-               real_current_font.realize(layoutfont,
-                                         bview->buffer()->params.language);
-#endif
+
                return;
        }
 
@@ -739,11 +676,10 @@ void LyXText::setFont(BufferView * bview, LyXFont const & font, bool toggleall)
        freezeUndo();
        cursor = selection.start;
        while (cursor.par() != selection.end.par() ||
-              (cursor.pos() < selection.end.pos()))
+              cursor.pos() < selection.end.pos())
        {
                if (cursor.pos() < cursor.par()->size()) {
-                       // an open footnote should behave
-                       // like a closed one
+                       // an open footnote should behave like a closed one
                        setCharFont(bview, cursor.par(), cursor.pos(),
                                    font, toggleall);
                        cursor.pos(cursor.pos() + 1);
@@ -897,30 +833,30 @@ void LyXText::redoParagraphs(BufferView * bview, LyXCursor const & cur,
 
        if (tmprow && tmprow->next())
                setHeightOfRow(bview, tmprow->next());
+       updateCounters(bview);
 }
 
 
-bool LyXText::fullRebreak(BufferView * bview)
+void LyXText::fullRebreak(BufferView * bview)
 {
        if (!firstrow) {
                init(bview);
-               return true;
+               return;
        }
        if (need_break_row) {
                breakAgain(bview, need_break_row);
                need_break_row = 0;
-               return true;
+               return;
        }
-       return true;
 }
 
 
 // important for the screen
 
 
-/* the cursor set functions have a special mechanism. When they
- * realize, that you left an empty paragraph, they will delete it.
- * They also delete the corresponding row */
+// the cursor set functions have a special mechanism. When they
+// realize, that you left an empty paragraph, they will delete it.
+// They also delete the corresponding row
 
 // need the selection cursor:
 void LyXText::setSelection(BufferView * bview)
@@ -983,30 +919,26 @@ string const LyXText::selectionAsString(Buffer const * buffer,
                                        bool label) const
 {
        if (!selection.set()) return string();
-       string result;
 
-       // Special handling if the whole selection is within one paragraph
-       if (selection.start.par() == selection.end.par()) {
-               result += selection.start.par()->asString(buffer,
-                                                         selection.start.pos(),
-                                                         selection.end.pos(),
-                                                         label);
-               return result;
+       // should be const ...
+       Paragraph * startpar(selection.start.par());
+       Paragraph * endpar(selection.end.par());
+       pos_type const startpos(selection.start.pos());
+       pos_type const endpos(selection.end.pos());
+
+       if (startpar == endpar) {
+               return startpar->asString(buffer, startpos, endpos, label);
        }
 
-       // The selection spans more than one paragraph
+       string result;
 
        // First paragraph in selection
-       result += selection.start.par()->asString(buffer,
-                                                 selection.start.pos(),
-                                                 selection.start.par()->size(),
-                                                 label)
-               + "\n\n";
+       result += startpar->asString(buffer, startpos, startpar->size(), label) + "\n\n";
 
        // The paragraphs in between (if any)
        LyXCursor tmpcur(selection.start);
        tmpcur.par(tmpcur.par()->next());
-       while (tmpcur.par() != selection.end.par()) {
+       while (tmpcur.par() != endpar) {
                result += tmpcur.par()->asString(buffer, 0,
                                                 tmpcur.par()->size(),
                                                 label) + "\n\n";
@@ -1014,8 +946,7 @@ string const LyXText::selectionAsString(Buffer const * buffer,
        }
 
        // Last paragraph in selection
-       result += selection.end.par()->asString(buffer, 0,
-                                               selection.end.pos(), label);
+       result += endpar->asString(buffer, 0, endpos, label);
 
        return result;
 }
@@ -1044,7 +975,7 @@ void LyXText::cursorEnd(BufferView * bview) const
            || cursor.row()->next()->par() != cursor.row()->par()) {
                setCursor(bview, cursor.par(), rowLast(cursor.row()) + 1);
        } else {
-               if (cursor.par()->size() &&
+               if (!cursor.par()->empty() &&
                    (cursor.par()->getChar(rowLast(cursor.row())) == ' '
                     || cursor.par()->isNewline(rowLast(cursor.row())))) {
                        setCursor(bview, cursor.par(), rowLast(cursor.row()));
@@ -1108,53 +1039,48 @@ void LyXText::toggleFree(BufferView * bview,
 
 string LyXText::getStringToIndex(BufferView * bview)
 {
-       string idxstring;
-
        // Try implicit word selection
        // If there is a change in the language the implicit word selection
        // is disabled.
-       LyXCursor resetCursor = cursor;
-       bool implicitSelection = selectWordWhenUnderCursor(bview, PREVIOUS_WORD);
+       LyXCursor const reset_cursor = cursor;
+       bool const implicitSelection = selectWordWhenUnderCursor(bview, PREVIOUS_WORD);
 
-       if (!selection.set()) {
+       string idxstring;
+       if (!selection.set())
                bview->owner()->message(_("Nothing to index!"));
-               return string();
-       }
-       if (selection.start.par() != selection.end.par()) {
+       else if (selection.start.par() != selection.end.par())
                bview->owner()->message(_("Cannot index more than one paragraph!"));
-               return string();
-       }
+       else
+               idxstring = selectionAsString(bview->buffer(), false);
 
-       idxstring = selectionAsString(bview->buffer(), false);
+       // Reset cursors to their original position.
+       cursor = reset_cursor;
+       setCursor(bview, cursor.par(), cursor.pos());
+       selection.cursor = cursor;
 
-       // Implicit selections are cleared afterwards
-       //and cursor is set to the original position.
-       if (implicitSelection) {
+       // Clear the implicit selection.
+       if (implicitSelection)
                clearSelection();
-               cursor = resetCursor;
-               setCursor(bview, cursor.par(), cursor.pos());
-               selection.cursor = cursor;
-       }
+
        return idxstring;
 }
 
 
-pos_type LyXText::beginningOfMainBody(Buffer const * buf,
+pos_type LyXText::beginningOfMainBody(Buffer const * /*buf*/,
                             Paragraph const * par) const
 {
-       if (textclasslist[buf->params.textclass][
-                               par->layout()].labeltype != LABEL_MANUAL)
+       if (par->layout()->labeltype != LABEL_MANUAL)
                return 0;
        else
                return par->beginningOfMainBody();
 }
 
 
-/* the DTP switches for paragraphs. LyX will store them in the
-* first physicla paragraph. When a paragraph is broken, the top settings
-* rest, the bottom settings are given to the new one. So I can make shure,
-* they do not duplicate themself and you cannnot make dirty things with
-* them!  */
+// the DTP switches for paragraphs. LyX will store them in the first
+// physicla paragraph. When a paragraph is broken, the top settings rest,
+// the bottom settings are given to the new one. So I can make shure,
+// they do not duplicate themself and you cannnot make dirty things with
+// them!
 
 void LyXText::setParagraph(BufferView * bview,
                           bool line_top, bool line_bottom,
@@ -1191,8 +1117,6 @@ void LyXText::setParagraph(BufferView * bview,
 
 
        Paragraph * tmppar = selection.end.par();
-       LyXTextClass const & tclass =
-               textclasslist[bview->buffer()->params.textclass];
 
        while (tmppar != selection.start.par()->previous()) {
                setCursor(bview, tmppar, 0);
@@ -1207,12 +1131,12 @@ void LyXText::setParagraph(BufferView * bview,
                cursor.par()->params().spaceBottom(space_bottom);
                cursor.par()->params().spacing(spacing);
                // does the layout allow the new alignment?
-               LyXLayout const & layout = tclass[cursor.par()->layout()];
+               LyXLayout_ptr const & layout = cursor.par()->layout();
 
                if (align == LYX_ALIGN_LAYOUT)
-                       align = layout.align;
-               if (align & layout.alignpossible) {
-                       if (align == layout.align)
+                       align = layout->align;
+               if (align & layout->alignpossible) {
+                       if (align == layout->align)
                                cursor.par()->params().align(LYX_ALIGN_LAYOUT);
                        else
                                cursor.par()->params().align(align);
@@ -1235,86 +1159,22 @@ void LyXText::setParagraph(BufferView * bview,
 }
 
 
-char loweralphaCounter(int n)
-{
-       if (n < 1 || n > 26)
-               return '?';
-       else
-               return 'a' + n - 1;
-}
-
-
-namespace {
-
-inline
-char alphaCounter(int n)
-{
-       if (n < 1 || n > 26)
-               return '?';
-       else
-               return 'A' + n - 1;
-}
-
-
-inline
-char hebrewCounter(int n)
-{
-       static const char hebrew[22] = {
-               'à', 'á', 'â', 'ã', 'ä', 'Ã¥', 'æ', 'ç', 'è',
-               'é', 'ë', 'ì', 'î', 'ð', 'ñ', 'ò', 'ô', 'ö',
-               '÷', 'ø', 'ù', 'ú'
-       };
-       if (n < 1 || n > 22)
-               return '?';
-       else
-               return hebrew[n-1];
-}
-
-
-inline
-string const romanCounter(int n)
-{
-       static char const * roman[20] = {
-               "i",   "ii",  "iii", "iv", "v",
-               "vi",  "vii", "viii", "ix", "x",
-               "xi",  "xii", "xiii", "xiv", "xv",
-               "xvi", "xvii", "xviii", "xix", "xx"
-       };
-       if (n < 1 || n > 20)
-               return "??";
-       else
-               return roman[n-1];
-}
-
-} // namespace anon
-
-
 // set the counter of a paragraph. This includes the labels
 void LyXText::setCounter(Buffer const * buf, Paragraph * par) const
 {
-       LyXTextClass const & textclass = textclasslist[buf->params.textclass];
-       LyXLayout const & layout = textclass[par->layout()];
-
+       LyXTextClass const & textclass = buf->params.getLyXTextClass();
+       LyXLayout_ptr const & layout = par->layout();
 
-       // copy the prev-counters to this one,
-       // unless this is the first paragraph
        if (par->previous()) {
-               for (int i = 0; i < 10; ++i) {
-                       par->setCounter(i, par->previous()->getFirstCounter(i));
-               }
+
                par->params().appendix(par->previous()->params().appendix());
                if (!par->params().appendix() && par->params().startOfAppendix()) {
                        par->params().appendix(true);
-                       for (int i = 0; i < 10; ++i) {
-                               par->setCounter(i, 0);
-                       }
+                       textclass.counters().reset();
                }
                par->enumdepth = par->previous()->enumdepth;
                par->itemdepth = par->previous()->itemdepth;
        } else {
-               for (int i = 0; i < 10; ++i) {
-                       par->setCounter(i, 0);
-               }
                par->params().appendix(par->params().startOfAppendix());
                par->enumdepth = 0;
                par->itemdepth = 0;
@@ -1329,317 +1189,201 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const
         */
        if (par->previous()
            && par->previous()->getDepth() < par->getDepth()
-           && textclass[par->previous()->layout()].labeltype == LABEL_COUNTER_ENUMI
+           && par->previous()->layout()->labeltype == LABEL_COUNTER_ENUMI
            && par->enumdepth < 3
-           && layout.labeltype != LABEL_BIBLIO) {
+           && layout->labeltype != LABEL_BIBLIO) {
                par->enumdepth++;
        }
 
        // Maybe we have to decrement the enumeration depth, see note above
        if (par->previous()
            && par->previous()->getDepth() > par->getDepth()
-           && layout.labeltype != LABEL_BIBLIO) {
+           && layout->labeltype != LABEL_BIBLIO) {
                par->enumdepth = par->depthHook(par->getDepth())->enumdepth;
-               par->setCounter(6 + par->enumdepth,
-                               par->depthHook(par->getDepth())->getCounter(6 + par->enumdepth));
-               /* reset the counters.
-                * A depth change is like a breaking layout
-                */
-               for (int i = 6 + par->enumdepth + 1; i < 10; ++i)
-                       par->setCounter(i, 0);
        }
 
        if (!par->params().labelString().empty()) {
                par->params().labelString(string());
        }
 
-       if (layout.margintype == MARGIN_MANUAL) {
+       if (layout->margintype == MARGIN_MANUAL) {
                if (par->params().labelWidthString().empty()) {
-                       par->setLabelWidthString(layout.labelstring());
+                       par->setLabelWidthString(layout->labelstring());
                }
        } else {
                par->setLabelWidthString(string());
        }
 
        // is it a layout that has an automatic label?
-       if (layout.labeltype >=  LABEL_COUNTER_CHAPTER) {
+       if (layout->labeltype >= LABEL_COUNTER_CHAPTER) {
+               int const i = layout->labeltype - LABEL_COUNTER_CHAPTER;
+
+               ostringstream s;
+
+               if (i >= 0 && i <= buf->params.secnumdepth) {
+                       string numbertype;
+                       string langtype;
 
-               int i = layout.labeltype - LABEL_COUNTER_CHAPTER;
-               if (i >= 0 && i<= buf->params.secnumdepth) {
-                       par->incCounter(i);     // increment the counter
+                       textclass.counters().step(layout->latexname());
 
                        // Is there a label? Useful for Chapter layout
                        if (!par->params().appendix()) {
-                               if (!layout.labelstring().empty())
-                                       par->params().labelString(layout.labelstring());
-                               else
-                                       par->params().labelString(string());
+                               s << layout->labelstring();
                        } else {
-                               if (!layout.labelstring_appendix().empty())
-                                       par->params().labelString(layout.labelstring_appendix());
-                               else
-                                       par->params().labelString(string());
+                               s << layout->labelstring_appendix();
                        }
 
-                       ostringstream s;
-
+                       // Use of an integer is here less than elegant. For now.
+                       int head = textclass.maxcounter() - LABEL_COUNTER_CHAPTER;
                        if (!par->params().appendix()) {
-                               switch (2 * LABEL_COUNTER_CHAPTER -
-                                       textclass.maxcounter() + i) {
-                               case LABEL_COUNTER_CHAPTER:
-                                       s << par->getCounter(i);
-                                       break;
-                               case LABEL_COUNTER_SECTION:
-                                       s << par->getCounter(i - 1) << '.'
-                                         << par->getCounter(i);
-                                       break;
-                               case LABEL_COUNTER_SUBSECTION:
-                                       s << par->getCounter(i - 2) << '.'
-                                         << par->getCounter(i - 1) << '.'
-                                         << par->getCounter(i);
-                                       break;
-                               case LABEL_COUNTER_SUBSUBSECTION:
-                                       s << par->getCounter(i - 3) << '.'
-                                         << par->getCounter(i - 2) << '.'
-                                         << par->getCounter(i - 1) << '.'
-                                         << par->getCounter(i);
-
-                                       break;
-                               case LABEL_COUNTER_PARAGRAPH:
-                                       s << par->getCounter(i - 4) << '.'
-                                         << par->getCounter(i - 3) << '.'
-                                         << par->getCounter(i - 2) << '.'
-                                         << par->getCounter(i - 1) << '.'
-                                         << par->getCounter(i);
-                                       break;
-                               case LABEL_COUNTER_SUBPARAGRAPH:
-                                       s << par->getCounter(i - 5) << '.'
-                                         << par->getCounter(i - 4) << '.'
-                                         << par->getCounter(i - 3) << '.'
-                                         << par->getCounter(i - 2) << '.'
-                                         << par->getCounter(i - 1) << '.'
-                                         << par->getCounter(i);
-
-                                       break;
-                               default:
-                                       // Can this ever be reached? And in the
-                                       // case it is, how can this be correct?
-                                       // (Lgb)
-                                       s << par->getCounter(i) << '.';
-                                       break;
-                               }
-                       } else { // appendix
-                               switch (2 * LABEL_COUNTER_CHAPTER - textclass.maxcounter() + i) {
-                               case LABEL_COUNTER_CHAPTER:
-                                       if (par->isRightToLeftPar(buf->params))
-                                               s << hebrewCounter(par->getCounter(i));
-                                       else
-                                               s << alphaCounter(par->getCounter(i));
-                                       break;
-                               case LABEL_COUNTER_SECTION:
-                                       if (par->isRightToLeftPar(buf->params))
-                                               s << hebrewCounter(par->getCounter(i - 1));
-                                       else
-                                               s << alphaCounter(par->getCounter(i - 1));
-
-                                       s << '.'
-                                         << par->getCounter(i);
-
-                                       break;
-                               case LABEL_COUNTER_SUBSECTION:
-                                       if (par->isRightToLeftPar(buf->params))
-                                               s << hebrewCounter(par->getCounter(i - 2));
-                                       else
-                                               s << alphaCounter(par->getCounter(i - 2));
-
-                                       s << '.'
-                                         << par->getCounter(i-1) << '.'
-                                         << par->getCounter(i);
-
-                                       break;
-                               case LABEL_COUNTER_SUBSUBSECTION:
-                                       if (par->isRightToLeftPar(buf->params))
-                                               s << hebrewCounter(par->getCounter(i-3));
-                                       else
-                                               s << alphaCounter(par->getCounter(i-3));
-
-                                       s << '.'
-                                         << par->getCounter(i-2) << '.'
-                                         << par->getCounter(i-1) << '.'
-                                         << par->getCounter(i);
-
-                                       break;
-                               case LABEL_COUNTER_PARAGRAPH:
-                                       if (par->isRightToLeftPar(buf->params))
-                                               s << hebrewCounter(par->getCounter(i-4));
-                                       else
-                                               s << alphaCounter(par->getCounter(i-4));
-
-                                       s << '.'
-                                         << par->getCounter(i-3) << '.'
-                                         << par->getCounter(i-2) << '.'
-                                         << par->getCounter(i-1) << '.'
-                                         << par->getCounter(i);
-
-                                       break;
-                               case LABEL_COUNTER_SUBPARAGRAPH:
-                                       if (par->isRightToLeftPar(buf->params))
-                                               s << hebrewCounter(par->getCounter(i-5));
-                                       else
-                                               s << alphaCounter(par->getCounter(i-5));
-
-                                       s << '.'
-                                         << par->getCounter(i-4) << '.'
-                                         << par->getCounter(i-3) << '.'
-                                         << par->getCounter(i-2) << '.'
-                                         << par->getCounter(i-1) << '.'
-                                         << par->getCounter(i);
-
-                                       break;
-                               default:
-                                       // Can this ever be reached? And in the
-                                       // case it is, how can this be correct?
-                                       // (Lgb)
-                                       s << par->getCounter(i) << '.';
-
-                                       break;
-                               }
+                               numbertype = "sectioning";
+                       } else {
+                               numbertype = "appendix";
+                               if (par->isRightToLeftPar(buf->params))
+                                       langtype = "hebrew";
+                               else
+                                       langtype = "latin";
                        }
 
-                       par->params().labelString(par->params().labelString() +s.str().c_str());
-                       // We really want to remove the c_str as soon as
-                       // possible...
+                       s << textclass.counters()
+                               .numberLabel(layout->latexname(),
+                                            numbertype, langtype, head);
 
-                       for (i++; i < 10; ++i) {
-                               // reset the following counters
-                               par->setCounter(i, 0);
-                       }
-               } else if (layout.labeltype < LABEL_COUNTER_ENUMI) {
-                       for (i++; i < 10; ++i) {
-                               // reset the following counters
-                               par->setCounter(i, 0);
-                       }
-               } else if (layout.labeltype == LABEL_COUNTER_ENUMI) {
-                       par->incCounter(i + par->enumdepth);
-                       int number = par->getCounter(i + par->enumdepth);
+                       par->params().labelString(STRCONV(s.str()));
 
-                       ostringstream s;
+                       // reset enum counters
+                       textclass.counters().reset("enum");
+               } else if (layout->labeltype < LABEL_COUNTER_ENUMI) {
+                       textclass.counters().reset("enum");
+               } else if (layout->labeltype == LABEL_COUNTER_ENUMI) {
+                       // FIXME
+                       // Yes I know this is a really, really! bad solution
+                       // (Lgb)
+                       string enumcounter("enum");
 
                        switch (par->enumdepth) {
-                       case 1:
-                               if (par->isRightToLeftPar(buf->params))
-                                       s << '('
-                                         << hebrewCounter(number)
-                                         << ')';
-                               else
-                                       s << '('
-                                         << loweralphaCounter(number)
-                                         << ')';
-                               break;
                        case 2:
-                               if (par->isRightToLeftPar(buf->params))
-                                       s << '.' << romanCounter(number);
-                               else
-                                       s << romanCounter(number) << '.';
+                               enumcounter += 'i';
+                       case 1:
+                               enumcounter += 'i';
+                       case 0:
+                               enumcounter += 'i';
                                break;
                        case 3:
-                               if (par->isRightToLeftPar(buf->params))
-                                       s << '.'
-                                         << alphaCounter(number);
-                               else
-                                       s << alphaCounter(number)
-                                         << '.';
+                               enumcounter += "iv";
                                break;
                        default:
-                               if (par->isRightToLeftPar(buf->params))
-                                       s << '.' << number;
-                               else
-                                       s << number << '.';
+                               // not a valid enumdepth...
                                break;
                        }
 
-                       par->params().labelString(s.str().c_str());
-
-                       for (i += par->enumdepth + 1; i < 10; ++i) {
-                               // reset the following counters
-                               par->setCounter(i, 0);
-                       }
+                       textclass.counters().step(enumcounter);
 
+                       s << textclass.counters()
+                               .numberLabel(enumcounter, "enumeration");
+                       par->params().labelString(STRCONV(s.str()));
                }
-       } else if (layout.labeltype == LABEL_BIBLIO) {// ale970302
-               int i = LABEL_COUNTER_ENUMI - LABEL_COUNTER_CHAPTER + par->enumdepth;
-               par->incCounter(i);
-               int number = par->getCounter(i);
+       } else if (layout->labeltype == LABEL_BIBLIO) {// ale970302
+               textclass.counters().step("bibitem");
+               int number = textclass.counters().value("bibitem");
                if (!par->bibkey) {
-                       InsetCommandParams p("bibitem" );
+                       InsetCommandParams p("bibitem");
                        par->bibkey = new InsetBibKey(p);
                }
                par->bibkey->setCounter(number);
-               par->params().labelString(layout.labelstring());
+               par->params().labelString(layout->labelstring());
 
                // In biblio should't be following counters but...
        } else {
-               string s = layout.labelstring();
+               string s = layout->labelstring();
 
                // the caption hack:
-               if (layout.labeltype == LABEL_SENSITIVE) {
-                       bool isOK (par->inInset() && par->inInset()->owner() &&
-                                  (par->inInset()->owner()->lyxCode() == Inset::FLOAT_CODE));
+               if (layout->labeltype == LABEL_SENSITIVE) {
+                       Paragraph * tmppar = par;
+                       Inset * in = 0;
+                       bool isOK = false;
+                       while (tmppar && tmppar->inInset()
+                              // the single '=' is intended below
+                              && (in = tmppar->inInset()->owner())) {
+                               if (in->lyxCode() == Inset::FLOAT_CODE ||
+                                   in->lyxCode() == Inset::WRAP_CODE) {
+                                       isOK = true;
+                                       break;
+                               } else {
+                                       tmppar = in->parOwner();
+                               }
+                       }
 
                        if (isOK) {
-                               InsetFloat * tmp = static_cast<InsetFloat*>(par->inInset()->owner());
                                Floating const & fl
-                                       = floatList.getType(tmp->type());
-                               // We should get the correct number here too.
-                               s = fl.name() + " #:";
+                                       = textclass.floats().getType(static_cast<InsetFloat*>(in)->type());
+
+                               textclass.counters().step(fl.type());
+
+                               // Doesn't work... yet.
+#warning use boost.format
+#if USE_BOOST_FORMAT
+                               s = boost::io::str(boost::format(_("%1$s #:")) % fl.name());
+                               // s << boost::format(_("%1$s %1$d:")
+                               //        % fl.name()
+                               //        % buf->counters().value(fl.name());
+#else
+                               ostringstream o;
+                               //o << fl.name() << ' ' << buf->counters().value(fl.name()) << ":";
+                               o << fl.name() << " #:";
+                               s = STRCONV(o.str());
+#endif
                        } else {
-                               /* par->SetLayout(0);
-                                  s = layout->labelstring;  */
-                               s = (par->getParLanguage(buf->params)->lang() == "hebrew")
-                                       ? " :úåòîùî Ã¸Ã±Ã§" : "Senseless: ";
+                               // par->SetLayout(0);
+                               // s = layout->labelstring;
+                               s = _("Senseless: ");
                        }
                }
                par->params().labelString(s);
 
-               /* reset the enumeration counter. They are always resetted
-                * when there is any other layout between */
-               for (int i = 6 + par->enumdepth; i < 10; ++i)
-                       par->setCounter(i, 0);
+               // reset the enumeration counter. They are always reset
+               // when there is any other layout between
+               // Just fall-through between the cases so that all
+               // enum counters deeper than enumdepth is also reset.
+               switch (par->enumdepth) {
+               case 0:
+                       textclass.counters().reset("enumi");
+               case 1:
+                       textclass.counters().reset("enumii");
+               case 2:
+                       textclass.counters().reset("enumiii");
+               case 3:
+                       textclass.counters().reset("enumiv");
+               }
        }
 }
 
 
-// Updates all counters BEHIND the row. Changed paragraphs
-// with a dynamic left margin will be rebroken.
-void LyXText::updateCounters(BufferView * bview, Row * row) const
+// Updates all counters. Paragraphs with changed label string will be rebroken
+void LyXText::updateCounters(BufferView * bview) const
 {
-       Paragraph * par;
+       Row * row = firstrow;
+       Paragraph * par = row->par();
 
-       if (!row) {
-               row = firstrow;
-               par = row->par();
-       } else {
-               par = row->par()->next();
-       }
+       // CHECK if this is really needed. (Lgb)
+       bview->buffer()->params.getLyXTextClass().counters().reset();
 
        while (par) {
                while (row->par() != par)
                        row = row->next();
 
+               string const oldLabel = par->params().labelString();
+
+               // setCounter can potentially change the labelString.
                setCounter(bview->buffer(), par);
 
-               // now check for the headline layouts. remember that they
-               // have a dynamic left margin
-               LyXTextClass const & tclass =
-                       textclasslist[bview->buffer()->params.textclass];
-               LyXLayout const & layout = tclass[par->layout()];
+               string const & newLabel = par->params().labelString();
 
-               if (layout.margintype == MARGIN_DYNAMIC
-                   || layout.labeltype == LABEL_SENSITIVE) {
-                       // Rebreak the paragraph
+               if (oldLabel.empty() && !newLabel.empty()) {
                        removeParagraph(row);
                        appendParagraph(bview, row);
                }
+
                par = par->next();
        }
 }
@@ -1669,13 +1413,15 @@ void LyXText::insertInset(BufferView * bview, Inset * inset)
 
 void LyXText::copyEnvironmentType()
 {
-       copylayouttype = cursor.par()->layout();
+       copylayouttype = cursor.par()->layout()->name();
 }
 
 
 void LyXText::pasteEnvironmentType(BufferView * bview)
 {
-       setLayout(bview, copylayouttype);
+       // do nothing if there has been no previous copyEnvironmentType()
+       if (!copylayouttype.empty())
+               setLayout(bview, copylayouttype);
 }
 
 
@@ -1741,20 +1487,21 @@ void LyXText::cutSelection(BufferView * bview, bool doclear, bool realcut)
 
        // sometimes necessary
        if (doclear)
-               selection.start.par()->stripLeadingSpaces(bview->buffer()->params.textclass);
+               selection.start.par()->stripLeadingSpaces();
 
        redoParagraphs(bview, selection.start, endpar);
 
        // cutSelection can invalidate the cursor so we need to set
        // it anew. (Lgb)
-       cursor = selection.start;
+       // we prefer the end for when tracking changes
+       cursor = selection.end;
 
        // need a valid cursor. (Lgb)
        clearSelection();
 
        setCursor(bview, cursor.par(), cursor.pos());
        selection.cursor = cursor;
-       updateCounters(bview, cursor.row());
+       updateCounters(bview);
 }
 
 
@@ -1807,18 +1554,17 @@ void LyXText::pasteSelection(BufferView * bview)
        selection.cursor = cursor;
        setCursor(bview, actpar, pos);
        setSelection(bview);
-       updateCounters(bview, cursor.row());
+       updateCounters(bview);
 }
 
 
-// sets the selection over the number of characters of string, no check!!
-void LyXText::setSelectionOverString(BufferView * bview, string const & str)
+void LyXText::setSelectionRange(BufferView * bview, lyx::pos_type length)
 {
-       if (str.empty())
+       if (!length)
                return;
 
        selection.cursor = cursor;
-       for (string::size_type i = 0; i < str.length(); ++i)
+       while (length--)
                cursorRight(bview);
        setSelection(bview);
 }
@@ -1903,37 +1649,6 @@ void LyXText::insertStringAsParagraphs(BufferView * bview, string const & str)
 }
 
 
-bool LyXText::gotoNextInset(BufferView * bview,
-                           vector<Inset::Code> const & codes,
-                           string const & contents) const
-{
-       LyXCursor res = cursor;
-       Inset * inset;
-       do {
-               if (res.pos() < res.par()->size() - 1) {
-                       res.pos(res.pos() + 1);
-               } else  {
-                       res.par(res.par()->next());
-                       res.pos(0);
-               }
-
-       } while (res.par() &&
-                !(res.par()->isInset(res.pos())
-                  && (inset = res.par()->getInset(res.pos())) != 0
-                  && find(codes.begin(), codes.end(), inset->lyxCode())
-                  != codes.end()
-                  && (contents.empty() ||
-                      static_cast<InsetCommand *>(res.par()->getInset(res.pos()))->getContents()
-                      == contents)));
-
-       if (res.par()) {
-               setCursor(bview, res.par(), res.pos(), false);
-               return true;
-       }
-       return false;
-}
-
-
 void LyXText::checkParagraph(BufferView * bview, Paragraph * par,
                             pos_type pos)
 {
@@ -1976,10 +1691,7 @@ void LyXText::checkParagraph(BufferView * bview, Paragraph * par,
                status(bview, LyXText::NEED_MORE_REFRESH);
 
        // check the special right address boxes
-       if (textclasslist[bview->buffer()->params.textclass][
-                               par->layout()].margintype
-           == MARGIN_RIGHT_ADDRESS_BOX)
-       {
+       if (par->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                tmpcursor.par(par);
                tmpcursor.row(row);
                tmpcursor.y(y);
@@ -2073,6 +1785,7 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par,
        cur.iy(y + row->baseline());
        Inset * ins;
        if (row->previous() && pos &&
+               row->previous()->par() == row->par() &&
                par->getChar(pos) == Paragraph::META_INSET &&
                (ins=par->getInset(pos)) && (ins->needFullRow() || ins->display()))
        {
@@ -2088,7 +1801,11 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par,
 
        pos_type last = rowLastPrintable(old_row);
 
-       if (pos > last + 1) {
+       // None of these should happen, but we're scaredy-cats
+       if (pos > par->size()) {
+               pos = 0;
+               cur.pos(0);
+       } else if (pos > last + 1) {
                // This shouldn't happen.
                pos = last + 1;
                cur.pos(pos);
@@ -2119,7 +1836,7 @@ float LyXText::getCursorX(BufferView * bview, Row * row,
        float fill_label_hfill;
        // This call HAS to be here because of the BidiTables!!!
        prepareToPrint(bview, row, x, fill_separator, fill_hfill,
-                      fill_label_hfill);
+                      fill_label_hfill);
 
        if (last < row->pos())
                cursor_vpos = row->pos();
@@ -2147,13 +1864,13 @@ float LyXText::getCursorX(BufferView * bview, Row * row,
                pos_type pos = vis2log(vpos);
                if (main_body > 0 && pos == main_body - 1) {
                        x += fill_label_hfill +
-                               lyxfont::width(textclasslist[
-                                                      bview->buffer()->params.textclass][
-                                       row->par()->layout()]
-                                              .labelsep,
-                                              getLabelFont(bview->buffer(), row->par()));
-                       if (row->par()->isLineSeparator(main_body-1))
-                               x -= singleWidth(bview, row->par(),main_body-1);
+                               font_metrics::width(
+                                       row->par()->layout()->labelsep,
+                                       getLabelFont(bview->buffer(),
+                                                    row->par()));
+                       if (row->par()->isLineSeparator(main_body - 1))
+                               x -= singleWidth(bview,
+                                                row->par(), main_body - 1);
                }
                if (hfillExpansion(bview->buffer(), row, pos)) {
                        x += singleWidth(bview, row->par(), pos);
@@ -2254,6 +1971,30 @@ void LyXText::setCursorFromCoordinates(BufferView * bview, int x, int y) const
 }
 
 
+namespace {
+
+       /**
+        * return true if the cursor given is at the end of a row,
+        * and the next row is filled by an inset that spans an entire
+        * row.
+        */
+       bool beforeFullRowInset(Row & row, LyXCursor & cur) {
+               if (!row.next())
+                       return false;
+               Row const & next = *row.next();
+
+               if (next.pos() != cur.pos() || next.par() != cur.par())
+                       return false;
+               if (!cur.par()->isInset(cur.pos()))
+                       return false;
+               Inset const * inset = cur.par()->getInset(cur.pos());
+               if (inset->needFullRow() || inset->display())
+                       return true;
+               return false;
+       }
+}
+
+
 void LyXText::setCursorFromCoordinates(BufferView * bview, LyXCursor & cur,
                                       int x, int y) const
 {
@@ -2267,16 +2008,8 @@ void LyXText::setCursorFromCoordinates(BufferView * bview, LyXCursor & cur,
        cur.x(x);
        cur.y(y + row->baseline());
        cur.row(row);
-       Inset * ins;
-       if (row->next() && row->next()->pos() == cur.pos() &&
-               cur.par() == row->next()->par() &&
-               cur.par()->getChar(cur.pos()) == Paragraph::META_INSET &&
-               (ins=cur.par()->getInset(cur.pos())) &&
-               (ins->needFullRow() || ins->display()))
-       {
-               // we enter here if we put the cursor on the end of the row before
-               // a inset which uses a full row and in that case we HAVE to calculate
-               // the right (i) values.
+
+       if (beforeFullRowInset(*row, cur)) {
                pos_type last = rowLastPrintable(row);
                float x = getCursorX(bview, row->next(), cur.pos(), last, bound);
                cur.ix(int(x));
@@ -2331,10 +2064,9 @@ void LyXText::cursorUp(BufferView * bview, bool selecting) const
                int y1 = cursor.iy() - first_y;
                int y2 = y1;
                y -= first_y;
-               Inset * inset_hit =
-                       bview->checkInsetHit(const_cast<LyXText *>(this), x, y1);
+               Inset * inset_hit = checkInsetHit(bview, x, y1);
                if (inset_hit && isHighlyEditableInset(inset_hit)) {
-                       inset_hit->edit(bview, x, y - (y2 - y1), 0);
+                       inset_hit->edit(bview, x, y - (y2 - y1), mouse_button::none);
                }
        }
 #else
@@ -2351,14 +2083,13 @@ void LyXText::cursorDown(BufferView * bview, bool selecting) const
        int y = cursor.y() - cursor.row()->baseline() +
                cursor.row()->height() + 1;
        setCursorFromCoordinates(bview, x, y);
-       if (!selecting) {
+       if (!selecting && cursor.row() == cursor.irow()) {
                int y1 = cursor.iy() - first_y;
                int y2 = y1;
                y -= first_y;
-               Inset * inset_hit =
-                       bview->checkInsetHit(const_cast<LyXText *>(this), x, y1);
+               Inset * inset_hit = checkInsetHit(bview, x, y1);
                if (inset_hit && isHighlyEditableInset(inset_hit)) {
-                       inset_hit->edit(bview, x, y - (y2 - y1), 0);
+                       inset_hit->edit(bview, x, y - (y2 - y1), mouse_button::none);
                }
        }
 #else
@@ -2405,6 +2136,11 @@ void LyXText::fixCursorAfterDelete(BufferView * bview,
        if (cur.pos() > where.pos())
                cur.pos(cur.pos()-1);
 
+       // check also if we don't want to set the cursor on a spot behind the
+       // pagragraph because we erased the last character.
+       if (cur.pos() > cur.par()->size())
+               cur.pos(cur.par()->size());
+
        // recompute row et al. for this cursor
        setCursor(bview, cur, cur.par(), cur.pos(), cur.boundary());
 }
@@ -2418,10 +2154,8 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                return false;
 
        // We allow all kinds of "mumbo-jumbo" when freespacing.
-       if (textclasslist[bview->buffer()->params.textclass][
-                               old_cursor.par()->layout()].free_spacing
-           || old_cursor.par()->isFreeSpacing())
-       {
+       if (old_cursor.par()->layout()->free_spacing
+           || old_cursor.par()->isFreeSpacing()) {
                return false;
        }
 
@@ -2487,9 +2221,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                return false;
 
        // Do not delete empty paragraphs with keepempty set.
-       if (textclasslist
-           [bview->buffer()->params.textclass]
-           [old_cursor.par()->layout()].keepempty)
+       if (old_cursor.par()->layout()->keepempty)
                return false;
 
        // only do our magic if we changed paragraph
@@ -2500,7 +2232,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
        // we can't possibly have deleted a paragraph before this point
        bool deleted = false;
 
-       if ((old_cursor.par()->size() == 0
+       if ((old_cursor.par()->empty()
             || (old_cursor.par()->size() == 1
                 && old_cursor.par()->isLineSeparator(0)))) {
                // ok, we will delete anything
@@ -2538,7 +2270,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                         * there is another layout before */
                        if (refresh_row->next()) {
                                breakAgain(bview, refresh_row->next());
-                               updateCounters(bview, refresh_row);
+                               updateCounters(bview);
                        }
                        setHeightOfRow(bview, refresh_row);
                } else {
@@ -2571,7 +2303,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                           there is another layout before */
                        if (refresh_row) {
                                breakAgain(bview, refresh_row);
-                               updateCounters(bview, refresh_row->previous());
+                               updateCounters(bview);
                        }
                }
 
@@ -2585,7 +2317,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                }
        }
        if (!deleted) {
-               if (old_cursor.par()->stripLeadingSpaces(bview->buffer()->params.textclass)) {
+               if (old_cursor.par()->stripLeadingSpaces()) {
                        redoParagraphs(bview, old_cursor,
                                       old_cursor.par()->next());
                        // correct cursor y
@@ -2597,34 +2329,12 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
 }
 
 
-void LyXText::toggleAppendix(BufferView * bview)
-{
-       Paragraph * par = cursor.par();
-       bool start = !par->params().startOfAppendix();
-
-       // ensure that we have only one start_of_appendix in this document
-       Paragraph * tmp = ownerParagraph();
-       for (; tmp; tmp = tmp->next()) {
-               tmp->params().startOfAppendix(false);
-       }
-
-       par->params().startOfAppendix(start);
-
-       // we can set the refreshing parameters now
-       status(bview, LyXText::NEED_MORE_REFRESH);
-       refresh_y = 0;
-       refresh_row = 0; // not needed for full update
-       updateCounters(bview, 0);
-       setCursor(bview, cursor.par(), cursor.pos());
-}
-
-
 Paragraph * LyXText::ownerParagraph() const
 {
        if (inset_owner) {
                return inset_owner->paragraph();
        }
-       return bv_owner->buffer()->paragraph;
+       return &*(bv_owner->buffer()->paragraphs.begin());
 }
 
 
@@ -2633,7 +2343,7 @@ void LyXText::ownerParagraph(Paragraph * p) const
        if (inset_owner) {
                inset_owner->paragraph(p);
        } else {
-               bv_owner->buffer()->paragraph = p;
+               bv_owner->buffer()->paragraphs.set(p);
        }
 }
 
@@ -2657,9 +2367,8 @@ LyXText::text_status LyXText::status() const
 
 void LyXText::status(BufferView * bview, LyXText::text_status st) const
 {
-       // well as much as I know && binds more then || so the above and the
-       // below are identical (this for your known use of parentesis!)
-       // Now some explanation:
+       LyXText * t = bview->text;
+
        // We should only go up with refreshing code so this means that if
        // we have a MORE refresh we should never set it to LITTLE if we still
        // didn't handle it (and then it will be UNCHANGED. Now as long as
@@ -2670,17 +2379,14 @@ void LyXText::status(BufferView * bview, LyXText::text_status st) const
        // tell'em that it should redraw the actual row (where the inset
        // resides! Capito?!
 
-       if ((status_ != NEED_MORE_REFRESH)
-           || (status_ == NEED_MORE_REFRESH
-               && st != NEED_VERY_LITTLE_REFRESH))
-       {
+       if (status_ != NEED_MORE_REFRESH || st != NEED_VERY_LITTLE_REFRESH) {
                status_ = st;
                if (inset_owner && st != UNCHANGED) {
-                       bview->text->status(bview, NEED_VERY_LITTLE_REFRESH);
-                       if (!bview->text->refresh_row) {
-                               bview->text->refresh_row = bview->text->cursor.row();
-                               bview->text->refresh_y = bview->text->cursor.y() -
-                                       bview->text->cursor.row()->baseline();
+                       t->status(bview, NEED_VERY_LITTLE_REFRESH);
+                       if (!t->refresh_row) {
+                               t->refresh_row = t->cursor.row();
+                               t->refresh_y = t->cursor.y() -
+                                       t->cursor.row()->baseline();
                        }
                }
        }