]> git.lyx.org Git - lyx.git/blobdiff - src/text2.C
Oops...
[lyx.git] / src / text2.C
index 04d3b35de579343b146223feab67e59ef4ff1887..bb72fc1778c531b10e72178234b03e5f423a1278 100644 (file)
 
 #include <config.h>
 
-#ifdef __GNUG__
-#pragma implementation "lyxtext.h"
-#endif
-
 #include "lyxtext.h"
 #include "LString.h"
 #include "paragraph.h"
 #include "counters.h"
 
 #include "insets/inseterror.h"
-#include "insets/insetbib.h"
+#include "insets/insetbibitem.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::endl;
@@ -53,18 +52,18 @@ using lyx::pos_type;
 
 
 LyXText::LyXText(BufferView * bv)
-       : number_of_rows(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),
+       : height(0), width(0), first_y(0),
+         inset_owner(0), the_locking_inset(0), need_break_row(0),
+         refresh_y(0), refresh_row(0), bv_owner(bv),
          status_(LyXText::UNCHANGED), firstrow(0), lastrow(0)
 {}
 
 
 LyXText::LyXText(InsetText * inset)
-       :  number_of_rows(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)
+       : height(0), width(0), first_y(0),
+         inset_owner(inset), the_locking_inset(0), need_break_row(0),
+         refresh_y(0), refresh_row(0), bv_owner(0),
+         status_(LyXText::UNCHANGED), firstrow(0), lastrow(0)
 {}
 
 
@@ -84,7 +83,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;
@@ -98,6 +97,8 @@ void LyXText::init(BufferView * bview, bool reinit)
        }
        setCursorIntern(bview, firstrow->par(), 0);
        selection.cursor = cursor;
+
+       updateCounters(bview);
 }
 
 
@@ -127,21 +128,12 @@ LyXFont const realizeFont(LyXFont const & font,
        while (par && par_depth && !tmpfont.resolved()) {
                par = par->outerHook();
                if (par) {
-#ifndef INHERIT_LANGUAGE
                        tmpfont.realize(par->layout()->font);
-#else
-                       tmpfont.realize(tclass[par->layout()]->font,
-                                       buf->params.language);
-#endif
                        par_depth = par->getDepth();
                }
        }
 
-#ifndef INHERIT_LANGUAGE
        tmpfont.realize(tclass.defaultfont());
-#else
-       tmpfont.realize(tclass.defaultfont(), buf->params.language);
-#endif
 
        return tmpfont;
 }
@@ -166,25 +158,17 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par,
        // We specialize the 95% common case:
        if (!par->getDepth()) {
                if (layout->labeltype == LABEL_MANUAL
-                   && pos < beginningOfMainBody(buf, par)) {
+                   && pos < par->beginningOfMainBody()) {
                        // 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
                } 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
                }
        }
 
@@ -192,7 +176,7 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par,
 
        LyXFont layoutfont;
 
-       if (pos < beginningOfMainBody(buf, par)) {
+       if (pos < par->beginningOfMainBody()) {
                // 1% goes here
                layoutfont = layout->labelfont;
        } else {
@@ -201,11 +185,8 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par,
        }
 
        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);
 
@@ -270,7 +251,7 @@ void LyXText::setCharFont(Buffer const * buf, Paragraph * par,
        // Get concrete layout font to reduce against
        LyXFont layoutfont;
 
-       if (pos < beginningOfMainBody(buf, par))
+       if (pos < par->beginningOfMainBody())
                layoutfont = layout->labelfont;
        else
                layoutfont = layout->font;
@@ -281,20 +262,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(tp->layout()->font);
-#else
-                               layoutfont.realize(tclass[tp->layout()].font,
-                                                  buf->params.language);
-#endif
                }
        }
 
-#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);
@@ -331,7 +303,6 @@ void LyXText::insertRow(Row * row, Paragraph * par,
 
        if (row == lastrow)
                lastrow = tmprow;
-       ++number_of_rows;
 }
 
 
@@ -359,7 +330,6 @@ void LyXText::removeRow(Row * row) const
        height -= row->height(); // the text becomes smaller
 
        delete row;
-       --number_of_rows;       // one row less
 }
 
 
@@ -382,10 +352,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 position 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) {
@@ -400,14 +368,11 @@ void LyXText::insertParagraph(BufferView * bview, Paragraph * par,
 
 Inset * LyXText::getInset() const
 {
-       Inset * inset = 0;
-       if (cursor.pos() == 0 && cursor.par()->bibkey) {
-               inset = cursor.par()->bibkey;
-       } else if (cursor.pos() < cursor.par()->size()
+       if (cursor.pos() < cursor.par()->size()
                   && cursor.par()->isInset(cursor.pos())) {
-               inset = cursor.par()->getInset(cursor.pos());
+               return cursor.par()->getInset(cursor.pos());
        }
-       return inset;
+       return 0;
 }
 
 
@@ -444,21 +409,21 @@ void LyXText::toggleInset(BufferView * bview)
 
 /* used in setlayout */
 // Asger is not sure we want to do this...
-void LyXText::makeFontEntriesLayoutSpecific(Buffer const * buf,
-                                           Paragraph * par)
+void LyXText::makeFontEntriesLayoutSpecific(Buffer const & buf,
+                                           Paragraph & par)
 {
-       LyXLayout_ptr const & layout = par->layout();
+       LyXLayout_ptr const & layout = par.layout();
 
        LyXFont layoutfont;
-       for (pos_type pos = 0; pos < par->size(); ++pos) {
-               if (pos < beginningOfMainBody(buf, par))
+       for (pos_type pos = 0; pos < par.size(); ++pos) {
+               if (pos < par.beginningOfMainBody())
                        layoutfont = layout->labelfont;
                else
                        layoutfont = layout->font;
 
-               LyXFont tmpfont = par->getFontSettings(buf->params, pos);
+               LyXFont tmpfont = par.getFontSettings(buf.params, pos);
                tmpfont.reduce(layoutfont);
-               par->setFont(pos, tmpfont);
+               par.setFont(pos, tmpfont);
        }
 }
 
@@ -493,7 +458,7 @@ Paragraph * LyXText::setLayout(BufferView * bview,
 
        do {
                par->applyLayout(lyxlayout);
-               makeFontEntriesLayoutSpecific(bview->buffer(), par);
+               makeFontEntriesLayoutSpecific(*bview->buffer(), *par);
                Paragraph * fppar = par;
                fppar->params().spaceTop(lyxlayout->fill_top ?
                                         VSpace(VSpace::VFILL)
@@ -503,11 +468,6 @@ Paragraph * LyXText::setLayout(BufferView * bview,
                                            : VSpace(VSpace::NONE));
                if (lyxlayout->margintype == MARGIN_MANUAL)
                        par->setLabelWidthString(lyxlayout->labelstring());
-               if (lyxlayout->labeltype != LABEL_BIBLIO
-                   && fppar->bibkey) {
-                       delete fppar->bibkey;
-                       fppar->bibkey = 0;
-               }
                cur.par(par);
                par = par->next();
        } while (par != epar);
@@ -577,8 +537,6 @@ void  LyXText::incDepth(BufferView * bview)
        // and sel_end cursor
        cursor = selection.start;
 
-       bool anything_changed = false;
-
        while (true) {
                // NOTE: you can't change the depth of a bibliography entry
                if (cursor.par()->layout()->labeltype != LABEL_BIBLIO) {
@@ -588,7 +546,6 @@ void  LyXText::incDepth(BufferView * bview)
                                if (cursor.par()->getDepth()
                                    < prev->getMaxDepthAfter()) {
                                        cursor.par()->params().depth(cursor.par()->getDepth() + 1);
-                                       anything_changed = true;
                                }
                        }
                }
@@ -597,16 +554,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
@@ -685,8 +632,7 @@ void LyXText::setFont(BufferView * bview, LyXFont const & font, bool toggleall)
        if (!selection.set()) {
                // Determine basis font
                LyXFont layoutfont;
-               if (cursor.pos() < beginningOfMainBody(bview->buffer(),
-                                                      cursor.par())) {
+               if (cursor.pos() < cursor.par()->beginningOfMainBody()) {
                        layoutfont = getLabelFont(bview->buffer(),
                                                  cursor.par());
                } else {
@@ -702,12 +648,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;
        }
 
@@ -1018,15 +960,15 @@ void LyXText::cursorEnd(BufferView * bview) const
 {
        if (!cursor.row()->next()
            || cursor.row()->next()->par() != cursor.row()->par()) {
-               setCursor(bview, cursor.par(), rowLast(cursor.row()) + 1);
+               setCursor(bview, cursor.par(), cursor.row()->lastPos() + 1);
        } else {
                if (!cursor.par()->empty() &&
-                   (cursor.par()->getChar(rowLast(cursor.row())) == ' '
-                    || cursor.par()->isNewline(rowLast(cursor.row())))) {
-                       setCursor(bview, cursor.par(), rowLast(cursor.row()));
+                   (cursor.par()->getChar(cursor.row()->lastPos()) == ' '
+                    || cursor.par()->isNewline(cursor.row()->lastPos()))) {
+                       setCursor(bview, cursor.par(), cursor.row()->lastPos());
                } else {
                        setCursor(bview,cursor.par(),
-                                 rowLast(cursor.row()) + 1);
+                                 cursor.row()->lastPos() + 1);
                }
        }
 }
@@ -1084,44 +1026,30 @@ 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 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 = reset_cursor;
-               setCursor(bview, cursor.par(), cursor.pos());
-               selection.cursor = cursor;
-       }
-       return idxstring;
-}
-
 
-pos_type LyXText::beginningOfMainBody(Buffer const * /*buf*/,
-                            Paragraph const * par) const
-{
-       if (par->layout()->labeltype != LABEL_MANUAL)
-               return 0;
-       else
-               return par->beginningOfMainBody();
+       return idxstring;
 }
 
 
@@ -1219,7 +1147,7 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const
                par->params().appendix(par->previous()->params().appendix());
                if (!par->params().appendix() && par->params().startOfAppendix()) {
                        par->params().appendix(true);
-                       buf->counters().reset();
+                       textclass.counters().reset();
                }
                par->enumdepth = par->previous()->enumdepth;
                par->itemdepth = par->previous()->itemdepth;
@@ -1264,30 +1192,25 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const
        }
 
        // 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;
 
-               int i = layout->labeltype - LABEL_COUNTER_CHAPTER;
-               string numbertype, langtype;
                ostringstream s;
 
-               if (i >= 0 && i<= buf->params.secnumdepth) {
+               if (i >= 0 && i <= buf->params.secnumdepth) {
+                       string numbertype;
+                       string langtype;
 
-                       buf->counters().step(buf->counters().sects[i]);
+                       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();
                        }
 
-                       // Use if an integer is here less than elegant. For now.
+                       // Use of an integer is here less than elegant. For now.
                        int head = textclass.maxcounter() - LABEL_COUNTER_CHAPTER;
                        if (!par->params().appendix()) {
                                numbertype = "sectioning";
@@ -1299,35 +1222,51 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const
                                        langtype = "latin";
                        }
 
-                       s << buf->counters().numberLabel(buf->counters().sects[i],
-                               numbertype, langtype, head);
+                       s << textclass.counters()
+                               .numberLabel(layout->latexname(),
+                                            numbertype, langtype, head);
 
-                       par->params().labelString(par->params().labelString() + s.str().c_str());
-                       // We really want to remove the c_str as soon as
-                       // possible...
+                       par->params().labelString(STRCONV(s.str()));
 
                        // reset enum counters
-                       buf->counters().reset("enum");
+                       textclass.counters().reset("enum");
                } else if (layout->labeltype < LABEL_COUNTER_ENUMI) {
-                       buf->counters().reset("enum");
+                       textclass.counters().reset("enum");
                } else if (layout->labeltype == LABEL_COUNTER_ENUMI) {
-                       buf->counters().step(buf->counters().enums[par->enumdepth]);
+                       // FIXME
+                       // Yes I know this is a really, really! bad solution
+                       // (Lgb)
+                       string enumcounter("enum");
+
+                       switch (par->enumdepth) {
+                       case 2:
+                               enumcounter += 'i';
+                       case 1:
+                               enumcounter += 'i';
+                       case 0:
+                               enumcounter += 'i';
+                               break;
+                       case 3:
+                               enumcounter += "iv";
+                               break;
+                       default:
+                               // not a valid enumdepth...
+                               break;
+                       }
 
-                       s << buf->counters().numberLabel(buf->counters().enums[par->enumdepth],
-                               "enumeration", langtype);
-                       par->params().labelString(s.str().c_str());
+                       textclass.counters().step(enumcounter);
 
+                       s << textclass.counters()
+                               .numberLabel(enumcounter, "enumeration");
+                       par->params().labelString(STRCONV(s.str()));
                }
        } else if (layout->labeltype == LABEL_BIBLIO) {// ale970302
-               buf->counters().step("bibitem");
-               int number = buf->counters().value("bibitem");
-               if (!par->bibkey) {
-                       InsetCommandParams p("bibitem" );
-                       par->bibkey = new InsetBibKey(p);
+               textclass.counters().step("bibitem");
+               int number = textclass.counters().value("bibitem");
+               if (par->bibitem()) {
+                       par->bibitem()->setCounter(number);
+                       par->params().labelString(layout->labelstring());
                }
-               par->bibkey->setCounter(number);
-               par->params().labelString(layout->labelstring());
-
                // In biblio should't be following counters but...
        } else {
                string s = layout->labelstring();
@@ -1340,7 +1279,8 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const
                        while (tmppar && tmppar->inInset()
                               // the single '=' is intended below
                               && (in = tmppar->inInset()->owner())) {
-                               if (in->lyxCode() == Inset::FLOAT_CODE) {
+                               if (in->lyxCode() == Inset::FLOAT_CODE ||
+                                   in->lyxCode() == Inset::WRAP_CODE) {
                                        isOK = true;
                                        break;
                                } else {
@@ -1350,59 +1290,74 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const
 
                        if (isOK) {
                                Floating const & fl
-                                       = floatList.getType(static_cast<InsetFloat*>(in)->type());
+                                       = textclass.floats().getType(static_cast<InsetFloat*>(in)->type());
+
+                               textclass.counters().step(fl.type());
 
-                               buf->counters().step(fl.name());
-                               
                                // 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() << ' ' << buf->counters().value(fl.name()) << ":";
                                o << fl.name() << " #:";
-                               s = o.str();
+                               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 = par->enumdepth + 1; i < 4; i++) {
-                       buf->counters().set(buf->counters().enums[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.
+// Updates all counters. Paragraphs with changed label string will be rebroken
 void LyXText::updateCounters(BufferView * bview) const
 {
-       Paragraph * par;
-       
        Row * row = firstrow;
-       par = row->par();
+       Paragraph * par = row->par();
+
+       // CHECK if this is really needed. (Lgb)
+       bview->buffer()->params.getLyXTextClass().counters().reset();
 
-       bview->buffer()->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
-               LyXLayout_ptr const & layout = 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();
        }
 }
@@ -1438,7 +1393,9 @@ void LyXText::copyEnvironmentType()
 
 void LyXText::pasteEnvironmentType(BufferView * bview)
 {
-       setLayout(bview, copylayouttype);
+       // do nothing if there has been no previous copyEnvironmentType()
+       if (!copylayouttype.empty())
+               setLayout(bview, copylayouttype);
 }
 
 
@@ -1510,7 +1467,8 @@ void LyXText::cutSelection(BufferView * bview, bool doclear, bool realcut)
 
        // 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();
@@ -1574,14 +1532,13 @@ void LyXText::pasteSelection(BufferView * 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);
 }
@@ -1666,37 +1623,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)
 {
@@ -1708,7 +1634,7 @@ void LyXText::checkParagraph(BufferView * bview, Paragraph * par,
 
        // is there a break one row above
        if (row->previous() && row->previous()->par() == row->par()) {
-               z = nextBreakPoint(bview, row->previous(), workWidth(bview));
+               z = nextBreakPoint(bview, row->previous(), workWidth(*bview));
                if (z >= row->pos()) {
                        // set the dimensions of the row above
                        y -= row->previous()->height();
@@ -1728,12 +1654,12 @@ void LyXText::checkParagraph(BufferView * bview, Paragraph * par,
        }
 
        int const tmpheight = row->height();
-       pos_type const tmplast = rowLast(row);
+       pos_type const tmplast = row->lastPos();
        refresh_y = y;
        refresh_row = row;
 
        breakAgain(bview, row);
-       if (row->height() == tmpheight && rowLast(row) == tmplast)
+       if (row->height() == tmpheight && row->lastPos() == tmplast)
                status(bview, LyXText::NEED_VERY_LITTLE_REFRESH);
        else
                status(bview, LyXText::NEED_MORE_REFRESH);
@@ -1847,9 +1773,13 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par,
        // y is now the cursor baseline
        cur.y(y);
 
-       pos_type last = rowLastPrintable(old_row);
+       pos_type last = old_row->lastPrintablePos();
 
-       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);
@@ -1897,8 +1827,7 @@ float LyXText::getCursorX(BufferView * bview, Row * row,
                cursor_vpos = (bidi_level(pos) % 2 == 0)
                        ? log2vis(pos) : log2vis(pos) + 1;
 
-       pos_type main_body =
-               beginningOfMainBody(bview->buffer(), row->par());
+       pos_type main_body = row->par()->beginningOfMainBody();
        if ((main_body > 0) &&
            ((main_body-1 > last) ||
             !row->par()->isLineSeparator(main_body-1)))
@@ -1916,7 +1845,7 @@ float LyXText::getCursorX(BufferView * bview, Row * row,
                                x -= singleWidth(bview,
                                                 row->par(), main_body - 1);
                }
-               if (hfillExpansion(bview->buffer(), row, pos)) {
+               if (row->hfillExpansion(pos)) {
                        x += singleWidth(bview, row->par(), pos);
                        if (pos >= main_body)
                                x += fill_hfill;
@@ -2054,7 +1983,7 @@ void LyXText::setCursorFromCoordinates(BufferView * bview, LyXCursor & cur,
        cur.row(row);
 
        if (beforeFullRowInset(*row, cur)) {
-               pos_type last = rowLastPrintable(row);
+               pos_type last = row->lastPrintablePos();
                float x = getCursorX(bview, row->next(), cur.pos(), last, bound);
                cur.ix(int(x));
                cur.iy(y + row->height() + row->next()->baseline());
@@ -2108,8 +2037,7 @@ 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), mouse_button::none);
                }
@@ -2132,8 +2060,7 @@ void LyXText::cursorDown(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), mouse_button::none);
                }
@@ -2437,3 +2364,24 @@ void LyXText::status(BufferView * bview, LyXText::text_status st) const
                }
        }
 }
+
+
+bool LyXText::isTopLevel() const
+{
+       /// only the top-level lyxtext has a non-null bv owner
+       return bv_owner;
+}
+
+
+bool LyXText::isInInset() const
+{
+       return inset_owner;
+}
+
+
+int defaultRowHeight()
+{
+       LyXFont const font(LyXFont::ALL_SANE);
+       return int(font_metrics::maxAscent(font)
+                + font_metrics::maxDescent(font) * 1.5);
+}