]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
namespace grfx -> lyx::graphics
[lyx.git] / src / text.C
index baf693d5f4f8198478b083877075e785094ff8aa..8e68a70a32f797702cf157a8266ab2fa36d220dd 100644 (file)
 #include "language.h"
 #include "ParagraphParameters.h"
 #include "undo_funcs.h"
+#include "text_funcs.h"
 #include "WordLangTuple.h"
 #include "paragraph_funcs.h"
 #include "rowpainter.h"
+#include "lyxrow_funcs.h"
 
 #include "insets/insettext.h"
 
 
 #include <algorithm>
 
+using namespace lyx::support;
+
 using std::max;
 using std::min;
 using std::endl;
 using std::pair;
+
 using lyx::pos_type;
+using lyx::word_location;
+
+using namespace bv_funcs;
 
 /// top, right, bottom pixel margin
 extern int const PAPER_MARGIN = 20;
@@ -58,23 +66,100 @@ extern int const LEFT_MARGIN = PAPER_MARGIN + CHANGEBAR_MARGIN;
 extern int bibitemMaxWidth(BufferView *, LyXFont const &);
 
 
-int LyXText::workWidth(BufferView & bview) const
+BufferView * LyXText::bv()
+{
+       Assert(bv_owner != 0);
+       return bv_owner;
+}
+
+
+BufferView * LyXText::bv() const
+{
+       Assert(bv_owner != 0);
+       return bv_owner;
+}
+
+
+void LyXText::updateRowPositions()
+{
+       RowList::iterator rit = rows().begin();
+       RowList::iterator rend = rows().end();
+       for (int y = 0; rit != rend ; ++rit) {
+               rit->y(y);
+               y += rit->height();
+       }
+}
+
+
+int LyXText::top_y() const
+{
+       if (anchor_row_ == rowlist_.end())
+               return 0;
+
+       return anchor_row_->y() + anchor_row_offset_;
+}
+
+
+void LyXText::top_y(int newy)
+{
+       if (rows().empty())
+               return;
+
+       if (isInInset()) {
+               anchor_row_ = rows().begin();
+               anchor_row_offset_ = newy;
+               return;
+       }
+
+       lyxerr[Debug::GUI] << "setting top y = " << newy << endl;
+
+       int y = newy;
+       RowList::iterator rit = getRowNearY(y);
+
+       if (rit == anchor_row_ && anchor_row_offset_ == newy - y) {
+               lyxerr[Debug::GUI] << "top_y to same value, skipping update" << endl;
+               return;
+       }
+
+       anchor_row_ = rit;
+       anchor_row_offset_ = newy - y;
+       lyxerr[Debug::GUI] << "changing reference to row: " << &*anchor_row_
+              << " offset: " << anchor_row_offset_ << endl;
+       postPaint(0);
+}
+
+
+void LyXText::anchor_row(RowList::iterator rit)
+{
+       int old_y = top_y();
+       anchor_row_offset_ = 0;
+       anchor_row_ = rit;
+       anchor_row_offset_ = old_y - top_y();
+       lyxerr[Debug::GUI] << "anchor_row(): changing reference to row: "
+                          << &*anchor_row_ << " offset: "
+                          << anchor_row_offset_ << endl;
+}
+
+
+int LyXText::workWidth() const
 {
        if (inset_owner) {
                // FIXME: pass (const ?) ref
-               return inset_owner->textWidth(&bview);
+               return inset_owner->textWidth(bv());
        }
-       return bview.workWidth();
+       return bv()->workWidth();
 }
 
 
-int LyXText::workWidth(BufferView & bview, Inset * inset) const
+int LyXText::workWidth(Inset const * inset) const
 {
-       Paragraph * par = inset->parOwner();
-       lyx::Assert(par);
+       ParagraphList::iterator par = std::find(ownerParagraphs().begin(),
+                                               ownerParagraphs().end(),
+                                               *inset->parOwner());
+       //Assert(par);
 
        pos_type pos = par->getPositionOfInset(inset);
-       lyx::Assert(pos != -1);
+       Assert(pos != -1);
 
        LyXLayout_ptr const & layout = par->layout();
 
@@ -85,41 +170,44 @@ int LyXText::workWidth(BufferView & bview, Inset * inset) const
                Row dummyrow;
                dummyrow.par(par);
                dummyrow.pos(pos);
-               return workWidth(bview) - leftMargin(&bview, &dummyrow);
+               return workWidth() - leftMargin(dummyrow);
        } else {
                int dummy_y;
-               Row * row = getRow(par, pos, dummy_y);
-               Row * frow = row;
-               while (frow->previous() && frow->par() == frow->previous()->par())
-                       frow = frow->previous();
+               RowList::iterator row = getRow(par, pos, dummy_y);
+               RowList::iterator frow = row;
+               RowList::iterator beg = rowlist_.begin();
+
+               while (frow != beg && frow->par() == boost::prior(frow)->par())
+                       --frow;
 
                // FIXME: I don't understand this code - jbl
 
                unsigned int maxw = 0;
-               while (!frow->isParEnd()) {
+               while (!isParEnd(*this, frow)) {
                        if ((frow != row) && (maxw < frow->width()))
                                maxw = frow->width();
-                       frow = frow->next();
+                       ++frow;
                }
                if (maxw)
                        return maxw;
 
        }
-       return workWidth(bview);
+       return workWidth();
 }
 
 
-int LyXText::getRealCursorX(BufferView * bview) const
+int LyXText::getRealCursorX() const
 {
        int x = cursor.x();
-       if (the_locking_inset && (the_locking_inset->getLyXText(bview)!=this))
-               x = the_locking_inset->getLyXText(bview)->getRealCursorX(bview);
+       if (the_locking_inset && (the_locking_inset->getLyXText(bv())!= this))
+               x = the_locking_inset->getLyXText(bv())->getRealCursorX();
        return x;
 }
 
 
-unsigned char LyXText::transformChar(unsigned char c, Paragraph * par,
-                       pos_type pos) const
+#warning FIXME  This function seems to belong outside of LyxText.
+unsigned char LyXText::transformChar(unsigned char c, Paragraph const & par,
+                                    pos_type pos) const
 {
        if (!Encodings::is_arabic(c))
                if (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 && IsDigit(c))
@@ -127,14 +215,18 @@ unsigned char LyXText::transformChar(unsigned char c, Paragraph * par,
                else
                        return c;
 
-       unsigned char const prev_char = pos > 0 ? par->getChar(pos-1) : ' ';
+       unsigned char const prev_char = pos > 0 ? par.getChar(pos - 1) : ' ';
        unsigned char next_char = ' ';
 
-       for (pos_type i = pos+1; i < par->size(); ++i)
-               if (!Encodings::IsComposeChar_arabic(par->getChar(i))) {
-                       next_char = par->getChar(i);
+       pos_type const par_size = par.size();
+
+       for (pos_type i = pos + 1; i < par_size; ++i) {
+               unsigned char const par_char = par.getChar(i);
+               if (!Encodings::IsComposeChar_arabic(par_char)) {
+                       next_char = par_char;
                        break;
                }
+       }
 
        if (Encodings::is_arabic(next_char)) {
                if (Encodings::is_arabic(prev_char) &&
@@ -176,60 +268,103 @@ unsigned char LyXText::transformChar(unsigned char c, Paragraph * par,
 //
 // Lgb
 
-int LyXText::singleWidth(BufferView * bview, Paragraph * par,
-                        pos_type pos) const
+int LyXText::singleWidth(ParagraphList::iterator pit, pos_type pos) const
 {
-       char const c = par->getChar(pos);
-       return singleWidth(bview, par, pos, c);
+       if (pos >= pit->size())
+               return 0;
+
+       char const c = pit->getChar(pos);
+       return singleWidth(pit, pos, c);
 }
 
 
-int LyXText::singleWidth(BufferView * bview, Paragraph * par,
+int LyXText::singleWidth(ParagraphList::iterator pit,
                         pos_type pos, char c) const
 {
-       LyXFont const font = getFont(bview->buffer(), par, pos);
+       if (pos >= pit->size())
+               return 0;
+
+       LyXFont const font = getFont(bv()->buffer(), pit, pos);
 
        // The most common case is handled first (Asger)
        if (IsPrintable(c)) {
                if (font.language()->RightToLeft()) {
                        if (font.language()->lang() == "arabic" &&
                            (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 ||
-                            lyxrc.font_norm_type == LyXRC::ISO_10646_1))
+                            lyxrc.font_norm_type == LyXRC::ISO_10646_1)) {
                                if (Encodings::IsComposeChar_arabic(c))
                                        return 0;
                                else
-                                       c = transformChar(c, par, pos);
-                       else if (font.language()->lang() == "hebrew" &&
+                                       c = transformChar(c, *pit, pos);
+                       else if (font.language()->lang() == "hebrew" &&
                                 Encodings::IsComposeChar_hebrew(c))
                                return 0;
                }
                return font_metrics::width(c, font);
 
-       } else if (IsHfillChar(c)) {
-               // Because of the representation as vertical lines
-               return 3;
-       } else if (c == Paragraph::META_INSET) {
-               Inset * tmpinset = par->getInset(pos);
+       }
+
+       if (c == Paragraph::META_INSET) {
+               Inset * tmpinset = pit->getInset(pos);
                if (tmpinset) {
+                       if (tmpinset->lyxCode() == Inset::HFILL_CODE) {
+                               // Because of the representation as vertical lines
+                               return 3;
+                       }
 #if 1
+#warning inset->update FIXME
                        // this IS needed otherwise on initialitation we don't get the fill
                        // of the row right (ONLY on initialization if we read a file!)
                        // should be changed! (Jug 20011204)
-                       tmpinset->update(bview, font);
+                       tmpinset->update(bv());
 #endif
-                       return tmpinset->width(bview, font);
-               } else
-                       return 0;
+                       return tmpinset->width(bv(), font);
+               }
+               return 0;
+       }
 
-       } else if (IsSeparatorChar(c))
+       if (IsSeparatorChar(c))
                c = ' ';
-       else if (IsNewlineChar(c))
-               c = 'n';
        return font_metrics::width(c, font);
 }
 
 
-void LyXText::computeBidiTables(Buffer const * buf, Row * row) const
+lyx::pos_type LyXText::log2vis(lyx::pos_type pos) const
+{
+       if (bidi_start == -1)
+               return pos;
+       else
+               return log2vis_list[pos - bidi_start];
+}
+
+
+lyx::pos_type LyXText::vis2log(lyx::pos_type pos) const
+{
+       if (bidi_start == -1)
+               return pos;
+       else
+               return vis2log_list[pos - bidi_start];
+}
+
+
+lyx::pos_type LyXText::bidi_level(lyx::pos_type pos) const
+{
+       if (bidi_start == -1)
+               return 0;
+       else
+               return bidi_levels[pos - bidi_start];
+}
+
+
+bool LyXText::bidi_InRange(lyx::pos_type pos) const
+{
+       return bidi_start == -1 ||
+               (bidi_start <= pos && pos <= bidi_end);
+}
+
+
+void LyXText::computeBidiTables(Buffer const * buf,
+                               RowList::iterator row) const
 {
        bidi_same_direction = true;
        if (!lyxrc.rtl_support) {
@@ -237,7 +372,9 @@ void LyXText::computeBidiTables(Buffer const * buf, Row * row) const
                return;
        }
 
-       Inset * inset = row->par()->inInset();
+       ParagraphList::iterator row_par = row->par();
+
+       Inset * inset = row_par->inInset();
        if (inset && inset->owner() &&
            inset->owner()->lyxCode() == Inset::ERT_CODE) {
                bidi_start = -1;
@@ -245,7 +382,7 @@ void LyXText::computeBidiTables(Buffer const * buf, Row * row) const
        }
 
        bidi_start = row->pos();
-       bidi_end = row->lastPrintablePos();
+       bidi_end = lastPrintablePos(*this, row);
 
        if (bidi_start > bidi_end) {
                bidi_start = -1;
@@ -267,25 +404,25 @@ void LyXText::computeBidiTables(Buffer const * buf, Row * row) const
 
        pos_type stack[2];
        bool const rtl_par =
-               row->par()->isRightToLeftPar(buf->params);
+               row_par->isRightToLeftPar(buf->params);
        int level = 0;
        bool rtl = false;
        bool rtl0 = false;
-       pos_type const main_body = row->par()->beginningOfMainBody();
+       pos_type const body_pos = row_par->beginningOfBody();
 
        for (pos_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
-               bool is_space = row->par()->isLineSeparator(lpos);
+               bool is_space = row_par->isLineSeparator(lpos);
                pos_type const pos =
                        (is_space && lpos + 1 <= bidi_end &&
-                        !row->par()->isLineSeparator(lpos + 1) &&
-                        !row->par()->isNewline(lpos + 1))
+                        !row_par->isLineSeparator(lpos + 1) &&
+                        !row_par->isNewline(lpos + 1))
                        ? lpos + 1 : lpos;
-               LyXFont font = row->par()->getFontSettings(buf->params, pos);
+               LyXFont font = row_par->getFontSettings(buf->params, pos);
                if (pos != lpos && 0 < lpos && rtl0 && font.isRightToLeft() &&
                    font.number() == LyXFont::ON &&
-                   row->par()->getFontSettings(buf->params, lpos - 1).number()
+                   row_par->getFontSettings(buf->params, lpos - 1).number()
                    == LyXFont::ON) {
-                       font = row->par()->getFontSettings(buf->params, lpos);
+                       font = row_par->getFontSettings(buf->params, lpos);
                        is_space = false;
                }
 
@@ -294,8 +431,8 @@ void LyXText::computeBidiTables(Buffer const * buf, Row * row) const
                bool new_rtl0 = font.isRightToLeft();
                int new_level;
 
-               if (lpos == main_body - 1
-                   && row->pos() < main_body - 1
+               if (lpos == body_pos - 1
+                   && row->pos() < body_pos - 1
                    && is_space) {
                        new_level = (rtl_par) ? 1 : 0;
                        new_rtl = new_rtl0 = rtl_par;
@@ -356,7 +493,7 @@ void LyXText::computeBidiTables(Buffer const * buf, Row * row) const
 
 
 // This method requires a previous call to ComputeBidiTables()
-bool LyXText::isBoundary(Buffer const * buf, Paragraph * par,
+bool LyXText::isBoundary(Buffer const * buf, Paragraph const & par,
                         pos_type pos) const
 {
        if (!lyxrc.rtl_support || pos == 0)
@@ -371,12 +508,12 @@ bool LyXText::isBoundary(Buffer const * buf, Paragraph * par,
        bool const rtl = bidi_level(pos - 1) % 2;
        bool const rtl2 = bidi_InRange(pos)
                ? bidi_level(pos) % 2
-               : par->isRightToLeftPar(buf->params);
+               : par.isRightToLeftPar(buf->params);
        return rtl != rtl2;
 }
 
 
-bool LyXText::isBoundary(Buffer const * buf, Paragraph * par,
+bool LyXText::isBoundary(Buffer const * buf, Paragraph const & par,
                         pos_type pos, LyXFont const & font) const
 {
        if (!lyxrc.rtl_support)
@@ -385,22 +522,24 @@ bool LyXText::isBoundary(Buffer const * buf, Paragraph * par,
        bool const rtl = font.isVisibleRightToLeft();
        bool const rtl2 = bidi_InRange(pos)
                ? bidi_level(pos) % 2
-               : par->isRightToLeftPar(buf->params);
+               : par.isRightToLeftPar(buf->params);
        return rtl != rtl2;
 }
 
 
-int LyXText::leftMargin(BufferView * bview, Row const * row) const
+int LyXText::leftMargin(Row const & row) const
 {
        Inset * ins;
-       if ((row->par()->getChar(row->pos()) == Paragraph::META_INSET) &&
-               (ins=row->par()->getInset(row->pos())) &&
-               (ins->needFullRow() || ins->display()))
-               return LEFT_MARGIN;
+
+       if (row.pos() < row.par()->size())
+               if ((row.par()->getChar(row.pos()) == Paragraph::META_INSET) &&
+                   (ins = row.par()->getInset(row.pos())) &&
+                   (ins->needFullRow() || ins->display()))
+                       return LEFT_MARGIN;
 
        LyXTextClass const & tclass =
-               bview->buffer()->params.getLyXTextClass();
-       LyXLayout_ptr const & layout = row->par()->layout();
+               bv()->buffer()->params.getLyXTextClass();
+       LyXLayout_ptr const & layout = row.par()->layout();
 
        string parindent = layout->parindent;
 
@@ -411,39 +550,37 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
        // this is the way, LyX handles the LaTeX-Environments.
        // I have had this idea very late, so it seems to be a
        // later added hack and this is true
-       if (!row->par()->getDepth()) {
-               if (row->par()->layout() == tclass.defaultLayout()) {
+       if (!row.par()->getDepth()) {
+               if (row.par()->layout() == tclass.defaultLayout()) {
                        // find the previous same level paragraph
-                       if (row->par()->previous()) {
-                               Paragraph * newpar = row->par()
-                                       ->depthHook(row->par()->getDepth());
-                               if (newpar &&
-                                   newpar->layout()->nextnoindent)
+                       if (row.par() != ownerParagraphs().begin()) {
+                               ParagraphList::iterator newpit =
+                                       depthHook(row.par(), ownerParagraphs(),
+                                                 row.par()->getDepth());
+                               if (newpit == row.par() &&
+                                   newpit->layout()->nextnoindent)
                                        parindent.erase();
                        }
                }
        } else {
                // find the next level paragraph
 
-               Paragraph * newpar = row->par()->outerHook();
+               ParagraphList::iterator newpar = outerHook(row.par(),
+                                                          ownerParagraphs());
 
-               // make a corresponding row. Needed to call LeftMargin()
+               // make a corresponding row. Needed to call leftMargin()
 
                // check wether it is a sufficent paragraph
-               if (newpar && newpar->layout()->isEnvironment()) {
+               if (newpar != ownerParagraphs().end() &&
+                   newpar->layout()->isEnvironment()) {
                        Row dummyrow;
                        dummyrow.par(newpar);
                        dummyrow.pos(newpar->size());
-                       x = leftMargin(bview, &dummyrow);
-               } else {
-                       // this is no longer an error, because this function
-                       // is used to clear impossible depths after changing
-                       // a layout. Since there is always a redo,
-                       // LeftMargin() is always called
-                       row->par()->params().depth(0);
+                       x = leftMargin(dummyrow);
                }
 
-               if (newpar && row->par()->layout() == tclass.defaultLayout()) {
+               if (newpar != ownerParagraphs().end() &&
+                   row.par()->layout() == tclass.defaultLayout()) {
                        if (newpar->params().noindent())
                                parindent.erase();
                        else {
@@ -453,26 +590,27 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                }
        }
 
-       LyXFont const labelfont = getLabelFont(bview->buffer(), row->par());
+       LyXFont const labelfont = getLabelFont(bv()->buffer(), row.par());
        switch (layout->margintype) {
        case MARGIN_DYNAMIC:
                if (!layout->leftmargin.empty()) {
                        x += font_metrics::signedWidth(layout->leftmargin,
                                                  tclass.defaultfont());
                }
-               if (!row->par()->getLabelstring().empty()) {
+               if (!row.par()->getLabelstring().empty()) {
                        x += font_metrics::signedWidth(layout->labelindent,
                                                  labelfont);
-                       x += font_metrics::width(row->par()->getLabelstring(),
+                       x += font_metrics::width(row.par()->getLabelstring(),
                                            labelfont);
                        x += font_metrics::width(layout->labelsep, labelfont);
                }
                break;
        case MARGIN_MANUAL:
                x += font_metrics::signedWidth(layout->labelindent, labelfont);
-               if (row->pos() >= row->par()->beginningOfMainBody()) {
-                       if (!row->par()->getLabelWidthString().empty()) {
-                               x += font_metrics::width(row->par()->getLabelWidthString(),
+               // The width of an empty par, even with manual label, should be 0
+               if (!row.par()->empty() && row.pos() >= row.par()->beginningOfBody()) {
+                       if (!row.par()->getLabelWidthString().empty()) {
+                               x += font_metrics::width(row.par()->getLabelWidthString(),
                                               labelfont);
                                x += font_metrics::width(layout->labelsep, labelfont);
                        }
@@ -480,23 +618,23 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                break;
        case MARGIN_STATIC:
                x += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()) * 4
-                       / (row->par()->getDepth() + 4);
+                       / (row.par()->getDepth() + 4);
                break;
        case MARGIN_FIRST_DYNAMIC:
                if (layout->labeltype == LABEL_MANUAL) {
-                       if (row->pos() >= row->par()->beginningOfMainBody()) {
+                       if (row.pos() >= row.par()->beginningOfBody()) {
                                x += font_metrics::signedWidth(layout->leftmargin,
                                                          labelfont);
                        } else {
                                x += font_metrics::signedWidth(layout->labelindent,
                                                          labelfont);
                        }
-               } else if (row->pos()
+               } else if (row.pos()
                           // Special case to fix problems with
                           // theorems (JMarc)
                           || (layout->labeltype == LABEL_STATIC
                               && layout->latextype == LATEX_ENVIRONMENT
-                              && ! row->par()->isFirstInSequence())) {
+                              && !isFirstInSequence(row.par(), ownerParagraphs()))) {
                        x += font_metrics::signedWidth(layout->leftmargin,
                                                  labelfont);
                } else if (layout->labeltype != LABEL_TOP_ENVIRONMENT
@@ -506,7 +644,7 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                        x += font_metrics::signedWidth(layout->labelindent,
                                                  labelfont);
                        x += font_metrics::width(layout->labelsep, labelfont);
-                       x += font_metrics::width(row->par()->getLabelstring(),
+                       x += font_metrics::width(row.par()->getLabelstring(),
                                            labelfont);
                }
                break;
@@ -518,16 +656,17 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                // are *NOT* allowed in the LaTeX realisation of this layout.
 
                // find the first row of this paragraph
-               Row const * tmprow = row;
-               while (tmprow->previous()
-                      && tmprow->previous()->par() == row->par())
-                       tmprow = tmprow->previous();
+               RowList::iterator tmprit = rowlist_.begin();
+               while (tmprit != rowlist_.end()
+                      && tmprit->par() != row.par())
+                       ++tmprit;
 
-               int minfill = tmprow->fill();
-               while (tmprow->next() && tmprow->next()->par() == row->par()) {
-                       tmprow = tmprow->next();
-                       if (tmprow->fill() < minfill)
-                               minfill = tmprow->fill();
+               int minfill = tmprit->fill();
+               while (boost::next(tmprit) != rowlist_.end() &&
+                      boost::next(tmprit)->par() == row.par()) {
+                       ++tmprit;
+                       if (tmprit->fill() < minfill)
+                               minfill = tmprit->fill();
                }
 
                x += font_metrics::signedWidth(layout->leftmargin,
@@ -537,44 +676,44 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
        break;
        }
 
-       if ((workWidth(*bview) > 0) &&
-               !row->par()->params().leftIndent().zero())
+       if ((workWidth() > 0) &&
+               !row.par()->params().leftIndent().zero())
        {
-               LyXLength const len = row->par()->params().leftIndent();
+               LyXLength const len = row.par()->params().leftIndent();
                int const tw = inset_owner ?
-                       inset_owner->latexTextWidth(bview) : workWidth(*bview);
+                       inset_owner->latexTextWidth(bv()) : workWidth();
                x += len.inPixels(tw);
        }
 
-       LyXAlignment align; // wrong type
+       LyXAlignment align;
 
-       if (row->par()->params().align() == LYX_ALIGN_LAYOUT)
+       if (row.par()->params().align() == LYX_ALIGN_LAYOUT)
                align = layout->align;
        else
-               align = row->par()->params().align();
+               align = row.par()->params().align();
 
        // set the correct parindent
-       if (row->pos() == 0) {
+       if (row.pos() == 0) {
                if ((layout->labeltype == LABEL_NO_LABEL
                     || layout->labeltype == LABEL_TOP_ENVIRONMENT
                     || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT
                     || (layout->labeltype == LABEL_STATIC
                         && layout->latextype == LATEX_ENVIRONMENT
-                        && ! row->par()->isFirstInSequence()))
+                        && !isFirstInSequence(row.par(), ownerParagraphs())))
                    && align == LYX_ALIGN_BLOCK
-                   && !row->par()->params().noindent()
+                   && !row.par()->params().noindent()
                        // in tabulars and ert paragraphs are never indented!
-                       && (!row->par()->inInset() || !row->par()->inInset()->owner() ||
-                               (row->par()->inInset()->owner()->lyxCode() != Inset::TABULAR_CODE &&
-                                row->par()->inInset()->owner()->lyxCode() != Inset::ERT_CODE))
-                   && (row->par()->layout() != tclass.defaultLayout() ||
-                       bview->buffer()->params.paragraph_separation ==
+                       && (!row.par()->inInset() || !row.par()->inInset()->owner() ||
+                               (row.par()->inInset()->owner()->lyxCode() != Inset::TABULAR_CODE &&
+                                row.par()->inInset()->owner()->lyxCode() != Inset::ERT_CODE))
+                   && (row.par()->layout() != tclass.defaultLayout() ||
+                       bv()->buffer()->params.paragraph_separation ==
                        BufferParams::PARSEP_INDENT)) {
                        x += font_metrics::signedWidth(parindent,
                                                  tclass.defaultfont());
                } else if (layout->labeltype == LABEL_BIBLIO) {
                        // ale970405 Right width for bibitems
-                       x += bibitemMaxWidth(bview, tclass.defaultfont());
+                       x += bibitemMaxWidth(bv(), tclass.defaultfont());
                }
        }
 
@@ -585,10 +724,12 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
 int LyXText::rightMargin(Buffer const & buf, Row const & row) const
 {
        Inset * ins;
-       if ((row.par()->getChar(row.pos()) == Paragraph::META_INSET) &&
-               (ins=row.par()->getInset(row.pos())) &&
-               (ins->needFullRow() || ins->display()))
-               return PAPER_MARGIN;
+
+       if (row.pos() < row.par()->size())
+               if ((row.par()->getChar(row.pos()) == Paragraph::META_INSET) &&
+                   (ins = row.par()->getInset(row.pos())) &&
+                   (ins->needFullRow() || ins->display()))
+                       return PAPER_MARGIN;
 
        LyXTextClass const & tclass = buf.params.getLyXTextClass();
        LyXLayout_ptr const & layout = row.par()->layout();
@@ -597,37 +738,6 @@ int LyXText::rightMargin(Buffer const & buf, Row const & row) const
                + font_metrics::signedWidth(tclass.rightmargin(),
                                       tclass.defaultfont());
 
-       // this is the way, LyX handles the LaTeX-Environments.
-       // I have had this idea very late, so it seems to be a
-       // later added hack and this is true
-       if (row.par()->getDepth()) {
-               // find the next level paragraph
-
-               Paragraph const * newpar = row.par();
-
-               do {
-                       newpar = newpar->previous();
-               } while (newpar
-                        && newpar->getDepth() >= row.par()->getDepth());
-
-               // make a corresponding row. Needed to call LeftMargin()
-
-               // check wether it is a sufficent paragraph
-               if (newpar && newpar->layout()->isEnvironment()) {
-                       Row dummyrow;
-                       dummyrow.par(const_cast<Paragraph *>(newpar));
-                       dummyrow.pos(0);
-                       x = rightMargin(buf, dummyrow);
-               } else {
-                       // this is no longer an error, because this function
-                       // is used to clear impossible depths after changing
-                       // a layout. Since there is always a redo,
-                       // LeftMargin() is always called
-                       row.par()->params().depth(0);
-               }
-       }
-
-       //lyxerr << "rightmargin: " << layout->rightmargin << endl;
        x += font_metrics::signedWidth(layout->rightmargin,
                                       tclass.defaultfont())
                * 4 / (row.par()->getDepth() + 4);
@@ -635,13 +745,13 @@ int LyXText::rightMargin(Buffer const & buf, Row const & row) const
 }
 
 
-int LyXText::labelEnd(BufferView & bview, Row const & row) const
+int LyXText::labelEnd(Row const & row) const
 {
        if (row.par()->layout()->margintype == MARGIN_MANUAL) {
                Row tmprow = row;
                tmprow.pos(row.par()->size());
-               // just the beginning of the main body
-               return leftMargin(&bview, &tmprow);
+               // return the beginning of the body
+               return leftMargin(tmprow);
        }
 
        // LabelEnd is only needed if the layout
@@ -650,208 +760,244 @@ int LyXText::labelEnd(BufferView & bview, Row const & row) const
 }
 
 
-// get the next breakpoint in a given paragraph
-pos_type
-LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
+namespace {
+
+// this needs special handling - only newlines count as a break point
+pos_type addressBreakPoint(pos_type i, Paragraph const & par)
+{
+       for (; i < par.size(); ++i) {
+               if (par.isNewline(i))
+                       return i;
+       }
+
+       return par.size();
+}
+
+};
+
+
+pos_type LyXText::rowBreakPoint(Row const & row) const
 {
-       Paragraph * par = row->par();
+       ParagraphList::iterator pit = row.par();
+
+       // maximum pixel width of a row.
+       int width = workWidth() - rightMargin(*bv()->buffer(), row);
 
+       // inset->textWidth() returns -1 via workWidth(),
+       // but why ?
        if (width < 0)
-               return par->size();
+               return pit->size();
 
-       pos_type const pos = row->pos();
+       LyXLayout_ptr const & layout = pit->layout();
 
-       // position of the last possible breakpoint
-       // -1 isn't a suitable value, but a flag
-       pos_type last_separator = -1;
-       width -= rightMargin(*bview->buffer(), *row);
+       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX)
+               return addressBreakPoint(row.pos(), *pit);
 
-       pos_type const main_body = par->beginningOfMainBody();
-       LyXLayout_ptr const & layout = par->layout();
+       pos_type const pos = row.pos();
+       pos_type const body_pos = pit->beginningOfBody();
+       pos_type const last = pit->size();
+       pos_type point = last;
+
+       if (pos == last)
+               return last;
+
+       // Now we iterate through until we reach the right margin
+       // or the end of the par, then choose the possible break
+       // nearest that.
+
+       int const left = leftMargin(row);
+       int x = left;
+
+       // pixel width since last breakpoint
+       int chunkwidth = 0;
+       bool fullrow = false;
 
        pos_type i = pos;
+       for (; i < last; ++i) {
+               if (pit->isNewline(i)) {
+                       point = i;
+                       break;
+               }
 
-       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
-               // special code for right address boxes, only newlines count
-               while (i < par->size()) {
-                       if (par->isNewline(i)) {
-                               last_separator = i;
-                               i = par->size() - 1; // this means break
-                               //x = width;
-                       } else if (par->isInset(i) && par->getInset(i)
-                               && par->getInset(i)->display()) {
-                               par->getInset(i)->display(false);
+               char const c = pit->getChar(i);
+
+               int thiswidth;
+
+               // add the auto-hfill from label end to the body
+               if (body_pos && i == body_pos) {
+                       thiswidth = font_metrics::width(layout->labelsep,
+                               getLabelFont(bv()->buffer(), pit));
+                       if (pit->isLineSeparator(i - 1))
+                               thiswidth -= singleWidth(pit, i - 1);
+                       int left_margin = labelEnd(row);
+                       if (thiswidth + x < left_margin)
+                               thiswidth = left_margin - x;
+                       thiswidth += singleWidth(pit, i, c);
+               } else {
+                       thiswidth = singleWidth(pit, i, c);
+               }
+
+               x += thiswidth;
+               chunkwidth += thiswidth;
+
+               Inset * in = pit->isInset(i) ? pit->getInset(i) : 0;
+               fullrow = (in && (in->display() || in->needFullRow()));
+
+               // break before a character that will fall off
+               // the right of the row
+               if (x >= width) {
+                       // if no break before or we are at an inset
+                       // that will take up a row, break here
+                       if (point == last || fullrow || chunkwidth >= (width - left)) {
+                               if (pos < i)
+                                       point = i - 1;
+                               else
+                                       point = i;
                        }
-                       ++i;
+                       break;
                }
-       } else {
-               // Last position is an invariant
-               pos_type const last = par->size();
-               // this is the usual handling
-               int x = leftMargin(bview, row);
-               bool doitonetime = true;
-               while (doitonetime || ((x < width) && (i < last))) {
-                       doitonetime = false;
-                       char const c = par->getChar(i);
-                       Inset * in = 0;
-                       if (c == Paragraph::META_INSET)
-                               in = par->getInset(i);
-                       if (IsNewlineChar(c)) {
-                               last_separator = i;
-                               x = width; // this means break
-                       } else if (in && !in->isChar()) {
-                               // check wether a Display() inset is
-                               // valid here. if not, change it to
-                               // non-display
-                               if (in->display() &&
-                                   (layout->isCommand() ||
-                                    (layout->labeltype == LABEL_MANUAL
-                                     && i < par->beginningOfMainBody())))
-                               {
-                                       // display istn't allowd
-                                       in->display(false);
-                                       x += singleWidth(bview, par, i, c);
-                               } else if (in->display() || in->needFullRow()) {
-                                       // So break the line here
-                                       if (i == pos) {
-                                               if (pos < last-1) {
-                                                       last_separator = i;
-                                                       if (par->isLineSeparator(i+1))
-                                                               ++last_separator;
-                                               } else
-                                                       last_separator = last; // to avoid extra rows
-                                       } else
-                                               last_separator = i - 1;
-                                       x = width;  // this means break
-                               } else {
-                                       x += singleWidth(bview, par, i, c);
-                                       // we have to check this separately as we could have a
-                                       // lineseparator and then the algorithm below would prefer
-                                       // that which IS wrong! We should always break on an inset
-                                       // if it's too long and not on the last separator.
-                                       // Maybe the only exeption is insets used as chars but
-                                       // then we would have to have a special function inside
-                                       // the inset to tell us this. Till then we leave it as
-                                       // it is now. (Jug 20020106)
-                                       if (pos < i && x >= width && last_separator >= 0)
-                                               last_separator = i - 1;
-                               }
-                       } else  {
-                               if (par->isLineSeparator(i))
-                                       last_separator = i;
-                               x += singleWidth(bview, par, i, c);
+
+               if (!in || in->isChar()) {
+                       // some insets are line separators too
+                       if (pit->isLineSeparator(i)) {
+                               point = i;
+                               chunkwidth = 0;
                        }
-                       ++i;
-                       if (i == main_body) {
-                               x += font_metrics::width(layout->labelsep,
-                                                   getLabelFont(bview->buffer(), par));
-                               if (par->isLineSeparator(i - 1))
-                                       x-= singleWidth(bview, par, i - 1);
-                               int left_margin = labelEnd(*bview, *row);
-                               if (x < left_margin)
-                                       x = left_margin;
+                       continue;
+               }
+
+               if (!fullrow)
+                       continue;
+
+               // full row insets start at a new row
+               if (i == pos) {
+                       if (pos < last - 1) {
+                               point = i;
+                               if (pit->isLineSeparator(i + 1))
+                                       ++point;
+                       } else {
+                               // to avoid extra rows
+                               point = last;
                        }
+               } else {
+                       point = i - 1;
                }
-               if ((pos+1 < i) && (last_separator < 0) && (x >= width))
-                       last_separator = i - 2;
-               else if ((pos < i) && (last_separator < 0) && (x >= width))
-                       last_separator = i - 1;
-               // end of paragraph is always a suitable separator
-               else if (i == last && x < width)
-                       last_separator = i;
+
+               return point;
        }
 
-       // well, if last_separator is still 0, the line isn't breakable.
-       // don't care and cut simply at the end
-       if (last_separator < 0) {
-               last_separator = i;
+       if (point == last && x >= width) {
+               // didn't find one, break at the point we reached the edge
+               point = i;
+       } else if (i == last && x < width) {
+               // found one, but we fell off the end of the par, so prefer
+               // that.
+               point = last;
        }
 
-       // manual labels cannot be broken in LaTeX, do not care
-       if (main_body && last_separator < main_body)
-               last_separator = main_body - 1;
+       // manual labels cannot be broken in LaTeX. But we
+       // want to make our on-screen rendering of footnotes
+       // etc. still break
+       if (!fullrow && body_pos && point < body_pos)
+               point = body_pos - 1;
 
-       return last_separator;
+       return point;
 }
 
 
 // returns the minimum space a row needs on the screen in pixel
-int LyXText::fill(BufferView & bview, Row & row, int paper_width) const
+int LyXText::fill(RowList::iterator row, int paper_width) const
 {
        if (paper_width < 0)
                return 0;
 
        int w;
        // get the pure distance
-       pos_type const last = row.lastPrintablePos();
+       pos_type const last = lastPrintablePos(*this, row);
+
+       ParagraphList::iterator pit = row->par();
+       LyXLayout_ptr const & layout = pit->layout();
 
        // special handling of the right address boxes
-       if (row.par()->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
-               int const tmpfill = row.fill();
-               row.fill(0); // the minfill in MarginLeft()
-               w = leftMargin(&bview, &row);
-               row.fill(tmpfill);
+       if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
+               int const tmpfill = row->fill();
+               row->fill(0); // the minfill in MarginLeft()
+               w = leftMargin(*row);
+               row->fill(tmpfill);
        } else
-               w = leftMargin(&bview, &row);
+               w = leftMargin(*row);
 
-       Paragraph * par = row.par();
-       LyXLayout_ptr const & layout = par->layout();
-
-       pos_type const main_body = par->beginningOfMainBody();
-       pos_type i = row.pos();
+       pos_type const body_pos = pit->beginningOfBody();
+       pos_type i = row->pos();
 
        while (i <= last) {
-               if (main_body > 0 && i == main_body) {
-                       w += font_metrics::width(layout->labelsep, getLabelFont(bview.buffer(), par));
-                       if (par->isLineSeparator(i - 1))
-                               w -= singleWidth(&bview, par, i - 1);
-                       int left_margin = labelEnd(bview, row);
+               if (body_pos > 0 && i == body_pos) {
+                       w += font_metrics::width(layout->labelsep, getLabelFont(bv()->buffer(), pit));
+                       if (pit->isLineSeparator(i - 1))
+                               w -= singleWidth(pit, i - 1);
+                       int left_margin = labelEnd(*row);
                        if (w < left_margin)
                                w = left_margin;
                }
-               w += singleWidth(&bview, par, i);
+               w += singleWidth(pit, i);
                ++i;
        }
-       if (main_body > 0 && main_body > last) {
-               w += font_metrics::width(layout->labelsep, getLabelFont(bview.buffer(), par));
-               if (last >= 0 && par->isLineSeparator(last))
-                       w -= singleWidth(&bview, par, last);
-               int const left_margin = labelEnd(bview, row);
+       if (body_pos > 0 && body_pos > last) {
+               w += font_metrics::width(layout->labelsep, getLabelFont(bv()->buffer(), pit));
+               if (last >= 0 && pit->isLineSeparator(last))
+                       w -= singleWidth(pit, last);
+               int const left_margin = labelEnd(*row);
                if (w < left_margin)
                        w = left_margin;
        }
 
-       int const fill = paper_width - w - rightMargin(*bview.buffer(), row);
+       int const fill = paper_width - w - rightMargin(*bv()->buffer(), *row);
+
+       // If this case happens, it means that our calculation
+       // of the widths of the chars when we do rowBreakPoint()
+       // went wrong for some reason. Typically in list bodies.
+       // Things just about hobble on anyway, though you'll end
+       // up with a "fill_separator" less than zero, which corresponds
+       // to inter-word spacing being too small. Hopefully this problem
+       // will die when the label hacks die.
+       if (lyxerr.debugging() && fill < 0) {
+               lyxerr[Debug::GUI] << "Eek, fill() was < 0: " << fill
+                       << " w " << w << " paper_width " << paper_width
+                       << " right margin " << rightMargin(*bv()->buffer(), *row) << endl;
+       }
+
        return fill;
 }
 
 
 // returns the minimum space a manual label needs on the screen in pixel
-int LyXText::labelFill(BufferView & bview, Row const & row) const
+int LyXText::labelFill(Row const & row) const
 {
-       pos_type last = row.par()->beginningOfMainBody();
+       ParagraphList::iterator pit = row.par();
 
-       lyx::Assert(last > 0);
+       pos_type last = pit->beginningOfBody();
+
+       Assert(last > 0);
 
        // -1 because a label ends either with a space that is in the label,
        // or with the beginning of a footnote that is outside the label.
        --last;
 
        // a separator at this end does not count
-       if (row.par()->isLineSeparator(last))
+       if (pit->isLineSeparator(last))
                --last;
 
        int w = 0;
        pos_type i = row.pos();
        while (i <= last) {
-               w += singleWidth(&bview, row.par(), i);
+               w += singleWidth(pit, i);
                ++i;
        }
 
        int fill = 0;
-       string const & labwidstr = row.par()->params().labelWidthString();
+       string const & labwidstr = pit->params().labelWidthString();
        if (!labwidstr.empty()) {
-               LyXFont const labfont = getLabelFont(bview.buffer(), row.par());
+               LyXFont const labfont = getLabelFont(bv()->buffer(), pit);
                int const labwidth = font_metrics::width(labwidstr, labfont);
                fill = max(labwidth - w, 0);
        }
@@ -868,11 +1014,12 @@ LColor::color LyXText::backgroundColor() const
                return LColor::background;
 }
 
-void LyXText::setHeightOfRow(BufferView * bview, Row * row) const
+
+void LyXText::setHeightOfRow(RowList::iterator rit)
 {
+       Assert(rit != rows().end());
+
        // get the maximum ascent and the maximum descent
-       int asc = 0;
-       int desc = 0;
        float layoutasc = 0;
        float layoutdesc = 0;
        float tmptop = 0;
@@ -886,27 +1033,26 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row) const
 
        // Correction: only the fontsize count. The other properties
        //  are taken from the layoutfont. Nicer on the screen :)
-       Paragraph * par = row->par();
-       Paragraph * firstpar = row->par();
+       ParagraphList::iterator pit = rit->par();
 
-       LyXLayout_ptr const & layout = firstpar->layout();
+       LyXLayout_ptr const & layout = pit->layout();
 
        // as max get the first character of this row then it can increase but not
        // decrease the height. Just some point to start with so we don't have to
        // do the assignment below too often.
-       LyXFont font = getFont(bview->buffer(), par, row->pos());
+       LyXFont font = getFont(bv()->buffer(), pit, rit->pos());
        LyXFont::FONT_SIZE const tmpsize = font.size();
-       font = getLayoutFont(bview->buffer(), par);
+       font = getLayoutFont(bv()->buffer(), pit);
        LyXFont::FONT_SIZE const size = font.size();
        font.setSize(tmpsize);
 
-       LyXFont labelfont = getLabelFont(bview->buffer(), par);
+       LyXFont labelfont = getLabelFont(bv()->buffer(), pit);
 
        float spacing_val = 1.0;
-       if (!row->par()->params().spacing().isDefault()) {
-               spacing_val = row->par()->params().spacing().getValue();
+       if (!pit->params().spacing().isDefault()) {
+               spacing_val = pit->params().spacing().getValue();
        } else {
-               spacing_val = bview->buffer()->params.spacing.getValue();
+               spacing_val = bv()->buffer()->params.spacing.getValue();
        }
        //lyxerr << "spacing_val = " << spacing_val << endl;
 
@@ -917,27 +1063,30 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row) const
                          layout->spacing.getValue() *
                          spacing_val);
 
-       pos_type const pos_end = row->lastPos();
+       pos_type const pos_end = lastPos(*this, rit);
        int labeladdon = 0;
        int maxwidth = 0;
 
-       // Check if any insets are larger
-       for (pos_type pos = row->pos(); pos <= pos_end; ++pos) {
-               if (row->par()->isInset(pos)) {
-                       tmpfont = getFont(bview->buffer(), row->par(), pos);
-                       tmpinset = row->par()->getInset(pos);
-                       if (tmpinset) {
+       if (!pit->empty()) {
+               // Check if any insets are larger
+               for (pos_type pos = rit->pos(); pos <= pos_end; ++pos) {
+                       if (pit->isInset(pos)) {
+                               tmpfont = getFont(bv()->buffer(), pit, pos);
+                               tmpinset = pit->getInset(pos);
+                               if (tmpinset) {
 #if 1 // this is needed for deep update on initialitation
-                               tmpinset->update(bview, tmpfont);
+#warning inset->update FIXME
+                                       tmpinset->update(bv());
 #endif
-                               asc = tmpinset->ascent(bview, tmpfont);
-                               desc = tmpinset->descent(bview, tmpfont);
-                               maxwidth += tmpinset->width(bview, tmpfont);
-                               maxasc = max(maxasc, asc);
-                               maxdesc = max(maxdesc, desc);
+                                       maxwidth += tmpinset->width(bv(), tmpfont);
+                                       maxasc = max(maxasc,
+                                                    tmpinset->ascent(bv(), tmpfont));
+                                       maxdesc = max(maxdesc,
+                                                     tmpinset->descent(bv(), tmpfont));
+                               }
+                       } else {
+                               maxwidth += singleWidth(pit, pos);
                        }
-               } else {
-                       maxwidth += singleWidth(bview, row->par(), pos);
                }
        }
 
@@ -945,72 +1094,70 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row) const
        // This is not completely correct, but we can live with the small,
        // cosmetic error for now.
        LyXFont::FONT_SIZE maxsize =
-               row->par()->highestFontInRange(row->pos(), pos_end, size);
+               pit->highestFontInRange(rit->pos(), pos_end, size);
        if (maxsize > font.size()) {
                font.setSize(maxsize);
-
-               asc = font_metrics::maxAscent(font);
-               desc = font_metrics::maxDescent(font);
-               if (asc > maxasc)
-                       maxasc = asc;
-               if (desc > maxdesc)
-                       maxdesc = desc;
+               maxasc = max(maxasc, font_metrics::maxAscent(font));
+               maxdesc = max(maxdesc, font_metrics::maxDescent(font));
        }
 
        // This is nicer with box insets:
        ++maxasc;
        ++maxdesc;
 
-       row->ascent_of_text(maxasc);
+       rit->ascent_of_text(maxasc);
 
        // is it a top line?
-       if (!row->pos() && (row->par() == firstpar)) {
+       if (!rit->pos()) {
 
                // some parksips VERY EASY IMPLEMENTATION
-               if (bview->buffer()->params.paragraph_separation ==
+               if (bv()->buffer()->params.paragraph_separation ==
                        BufferParams::PARSEP_SKIP)
                {
                        if (layout->isParagraph()
-                               && firstpar->getDepth() == 0
-                               && firstpar->previous())
+                               && pit->getDepth() == 0
+                               && pit != ownerParagraphs().begin())
                        {
-                               maxasc += bview->buffer()->params.getDefSkip().inPixels(*bview);
-                       } else if (firstpar->previous() &&
-                                  firstpar->previous()->layout()->isParagraph() &&
-                                  firstpar->previous()->getDepth() == 0)
+                               maxasc += bv()->buffer()->params.getDefSkip().inPixels(*bv());
+                       } else if (pit != ownerParagraphs().begin() &&
+                                  boost::prior(pit)->layout()->isParagraph() &&
+                                  boost::prior(pit)->getDepth() == 0)
                        {
                                // is it right to use defskip here too? (AS)
-                               maxasc += bview->buffer()->params.getDefSkip().inPixels(*bview);
+                               maxasc += bv()->buffer()->params.getDefSkip().inPixels(*bv());
                        }
                }
 
                // the top margin
-               if (!row->par()->previous() && isTopLevel())
+               if (pit == ownerParagraphs().begin() && !isInInset())
                        maxasc += PAPER_MARGIN;
 
                // add the vertical spaces, that the user added
-               maxasc += getLengthMarkerHeight(*bview, firstpar->params().spaceTop());
+               maxasc += getLengthMarkerHeight(*bv(), pit->params().spaceTop());
 
                // do not forget the DTP-lines!
                // there height depends on the font of the nearest character
-               if (firstpar->params().lineTop())
+               if (pit->params().lineTop())
 
-                       maxasc += 2 * font_metrics::ascent('x', getFont(bview->buffer(),
-                                       firstpar, 0));
+                       maxasc += 2 * font_metrics::ascent('x', getFont(bv()->buffer(),
+                                       pit, 0));
                // and now the pagebreaks
-               if (firstpar->params().pagebreakTop())
+               if (pit->params().pagebreakTop())
+                       maxasc += 3 * defaultRowHeight();
+
+               if (pit->params().startOfAppendix())
                        maxasc += 3 * defaultRowHeight();
 
                // This is special code for the chapter, since the label of this
                // layout is printed in an extra row
                if (layout->labeltype == LABEL_COUNTER_CHAPTER
-                       && bview->buffer()->params.secnumdepth >= 0)
+                       && bv()->buffer()->params.secnumdepth >= 0)
                {
                        float spacing_val = 1.0;
-                       if (!row->par()->params().spacing().isDefault()) {
-                               spacing_val = row->par()->params().spacing().getValue();
+                       if (!pit->params().spacing().isDefault()) {
+                               spacing_val = pit->params().spacing().getValue();
                        } else {
-                               spacing_val = bview->buffer()->params.spacing.getValue();
+                               spacing_val = bv()->buffer()->params.spacing.getValue();
                        }
 
                        labeladdon = int(font_metrics::maxDescent(labelfont) *
@@ -1025,14 +1172,14 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row) const
                if ((layout->labeltype == LABEL_TOP_ENVIRONMENT
                     || layout->labeltype == LABEL_BIBLIO
                     || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)
-                   && row->par()->isFirstInSequence()
-                   && !row->par()->getLabelstring().empty())
+                   && isFirstInSequence(pit, ownerParagraphs())
+                   && !pit->getLabelstring().empty())
                {
                        float spacing_val = 1.0;
-                       if (!row->par()->params().spacing().isDefault()) {
-                               spacing_val = row->par()->params().spacing().getValue();
+                       if (!pit->params().spacing().isDefault()) {
+                               spacing_val = pit->params().spacing().getValue();
                        } else {
-                               spacing_val = bview->buffer()->params.spacing.getValue();
+                               spacing_val = bv()->buffer()->params.spacing.getValue();
                        }
 
                        labeladdon = int(
@@ -1046,44 +1193,41 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row) const
                                + layout->labelbottomsep * defaultRowHeight());
                }
 
-               // and now the layout spaces, for example before and after a section,
-               // or between the items of a itemize or enumerate environment
-
-               if (!firstpar->params().pagebreakTop()) {
-                       Paragraph * prev = row->par()->previous();
-                       if (prev)
-                               prev = row->par()->depthHook(row->par()->getDepth());
-                       if (prev && prev->layout() == firstpar->layout() &&
-                               prev->getDepth() == firstpar->getDepth() &&
-                               prev->getLabelWidthString() == firstpar->getLabelWidthString())
+               // And now the layout spaces, for example before and after
+               // a section, or between the items of a itemize or enumerate
+               // environment.
+
+               if (!pit->params().pagebreakTop()) {
+                       ParagraphList::iterator prev =
+                               depthHook(pit, ownerParagraphs(),
+                                         pit->getDepth());
+                       if (prev != pit && prev->layout() == layout &&
+                               prev->getDepth() == pit->getDepth() &&
+                               prev->getLabelWidthString() == pit->getLabelWidthString())
                        {
                                layoutasc = (layout->itemsep * defaultRowHeight());
-                       } else if (row->previous()) {
+                       } else if (rit != rows().begin()) {
                                tmptop = layout->topsep;
 
-                               if (row->previous()->par()->getDepth() >= row->par()->getDepth())
-                                       tmptop -= row->previous()->par()->layout()->bottomsep;
+                               if (boost::prior(pit)->getDepth() >= pit->getDepth())
+                                       tmptop -= boost::prior(rit)->par()->layout()->bottomsep;
 
                                if (tmptop > 0)
                                        layoutasc = (tmptop * defaultRowHeight());
-                       } else if (row->par()->params().lineTop()) {
+                       } else if (pit->params().lineTop()) {
                                tmptop = layout->topsep;
 
                                if (tmptop > 0)
                                        layoutasc = (tmptop * defaultRowHeight());
                        }
 
-                       prev = row->par()->outerHook();
-                       if (prev)  {
+                       prev = outerHook(pit, ownerParagraphs());
+                       if (prev != ownerParagraphs().end())  {
                                maxasc += int(prev->layout()->parsep * defaultRowHeight());
-                       } else {
-                               if (firstpar->previous() &&
-                                       firstpar->previous()->getDepth() == 0 &&
-                                       firstpar->previous()->layout() !=
-                                       firstpar->layout())
-                               {
-                                       // avoid parsep
-                               } else if (firstpar->previous()) {
+                       } else if (pit != ownerParagraphs().begin()) {
+                               ParagraphList::iterator prior_pit = boost::prior(pit);
+                               if (prior_pit->getDepth() != 0 ||
+                                   prior_pit->layout() == layout) {
                                        maxasc += int(layout->parsep * defaultRowHeight());
                                }
                        }
@@ -1091,240 +1235,226 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row) const
        }
 
        // is it a bottom line?
-       if (row->par() == par
-               && (!row->next() || row->next()->par() != row->par())) {
+       RowList::iterator next_rit = boost::next(rit);
+       if (next_rit == rows().end() ||
+           next_rit->par() != pit) {
                // the bottom margin
-               if (!par->next() && isTopLevel())
+               ParagraphList::iterator nextpit = boost::next(pit);
+               if (nextpit == ownerParagraphs().end() &&
+                   !isInInset())
                        maxdesc += PAPER_MARGIN;
 
                // add the vertical spaces, that the user added
-               maxdesc += getLengthMarkerHeight(*bview, firstpar->params().spaceBottom());
+               maxdesc += getLengthMarkerHeight(*bv(), pit->params().spaceBottom());
 
                // do not forget the DTP-lines!
                // there height depends on the font of the nearest character
-               if (firstpar->params().lineBottom())
+               if (pit->params().lineBottom())
                        maxdesc += 2 * font_metrics::ascent('x',
-                                                      getFont(bview->buffer(),
-                                                              par,
-                                                              max(pos_type(0), par->size() - 1)));
+                                                      getFont(bv()->buffer(),
+                                                              pit,
+                                                              max(pos_type(0), pit->size() - 1)));
 
                // and now the pagebreaks
-               if (firstpar->params().pagebreakBottom())
+               if (pit->params().pagebreakBottom())
                        maxdesc += 3 * defaultRowHeight();
 
                // and now the layout spaces, for example before and after
                // a section, or between the items of a itemize or enumerate
                // environment
-               if (!firstpar->params().pagebreakBottom()
-                   && row->par()->next()) {
-                       Paragraph * nextpar = row->par()->next();
-                       Paragraph * comparepar = row->par();
+               if (!pit->params().pagebreakBottom()
+                   && nextpit != ownerParagraphs().end()) {
+                       ParagraphList::iterator comparepit = pit;
                        float usual = 0;
                        float unusual = 0;
 
-                       if (comparepar->getDepth() > nextpar->getDepth()) {
-                               usual = (comparepar->layout()->bottomsep * defaultRowHeight());
-                               comparepar = comparepar->depthHook(nextpar->getDepth());
-                               if (comparepar->layout()!= nextpar->layout()
-                                       || nextpar->getLabelWidthString() !=
-                                       comparepar->getLabelWidthString())
+                       if (comparepit->getDepth() > nextpit->getDepth()) {
+                               usual = (comparepit->layout()->bottomsep * defaultRowHeight());
+                               comparepit = depthHook(comparepit, ownerParagraphs(), nextpit->getDepth());
+                               if (comparepit->layout()!= nextpit->layout()
+                                       || nextpit->getLabelWidthString() !=
+                                       comparepit->getLabelWidthString())
                                {
-                                       unusual = (comparepar->layout()->bottomsep * defaultRowHeight());
+                                       unusual = (comparepit->layout()->bottomsep * defaultRowHeight());
                                }
                                if (unusual > usual)
                                        layoutdesc = unusual;
                                else
                                        layoutdesc = usual;
-                       } else if (comparepar->getDepth() ==  nextpar->getDepth()) {
+                       } else if (comparepit->getDepth() ==  nextpit->getDepth()) {
 
-                               if (comparepar->layout() != nextpar->layout()
-                                       || nextpar->getLabelWidthString() !=
-                                       comparepar->getLabelWidthString())
-                                       layoutdesc = int(comparepar->layout()->bottomsep * defaultRowHeight());
+                               if (comparepit->layout() != nextpit->layout()
+                                       || nextpit->getLabelWidthString() !=
+                                       comparepit->getLabelWidthString())
+                                       layoutdesc = int(comparepit->layout()->bottomsep * defaultRowHeight());
                        }
                }
        }
 
        // incalculate the layout spaces
-       maxasc += int(layoutasc * 2 / (2 + firstpar->getDepth()));
-       maxdesc += int(layoutdesc * 2 / (2 + firstpar->getDepth()));
+       maxasc += int(layoutasc * 2 / (2 + pit->getDepth()));
+       maxdesc += int(layoutdesc * 2 / (2 + pit->getDepth()));
 
        // calculate the new height of the text
-       height -= row->height();
+       height -= rit->height();
 
-       row->height(maxasc + maxdesc + labeladdon);
-       row->baseline(maxasc + labeladdon);
+       rit->height(maxasc + maxdesc + labeladdon);
+       rit->baseline(maxasc + labeladdon);
 
-       height += row->height();
+       height += rit->height();
 
-       row->top_of_text(row->baseline() - font_metrics::maxAscent(font));
+       rit->top_of_text(rit->baseline() - font_metrics::maxAscent(font));
 
        float x = 0;
        if (layout->margintype != MARGIN_RIGHT_ADDRESS_BOX) {
                float dummy;
                // this IS needed
-               row->width(maxwidth);
-               prepareToPrint(bview, row, x, dummy, dummy, dummy, false);
+               rit->width(maxwidth);
+               prepareToPrint(rit, x, dummy, dummy, dummy, false);
        }
-       row->width(int(maxwidth + x));
+       rit->width(int(maxwidth + x));
        if (inset_owner) {
-               Row * r = firstrow;
-               width = max(0, workWidth(*bview));
-               while (r) {
-                       if (r->width() > width)
-                               width = r->width();
-                       r = r->next();
+               width = max(0, workWidth());
+               RowList::iterator it = rows().begin();
+               RowList::iterator end = rows().end();
+               for (; it != end; ++it) {
+                       if (it->width() > width)
+                               width = it->width();
                }
        }
 }
 
 
-// Appends the implicit specified paragraph behind the specified row,
+// Appends the implicit specified paragraph before the specified row,
 // start at the implicit given position
-void LyXText::appendParagraph(BufferView * bview, Row * row) const
+void LyXText::appendParagraph(RowList::iterator rowit)
 {
-       bool not_ready = true;
+       Assert(rowit != rowlist_.end());
+
+       pos_type const last = rowit->par()->size();
+       bool done = false;
 
-       // The last character position of a paragraph is an invariant so we can
-       // safely get it here. (Asger)
-       pos_type const lastposition = row->par()->size();
        do {
-               // Get the next breakpoint
-               pos_type z = nextBreakPoint(bview, row, workWidth(*bview));
+               pos_type z = rowBreakPoint(*rowit);
 
-               Row * tmprow = row;
+               RowList::iterator tmprow = rowit;
 
-               // Insert the new row
-               if (z < lastposition) {
+               if (z < last) {
                        ++z;
-                       insertRow(row, row->par(), z);
-                       row = row->next();
-
-                       row->height(0);
-               } else
-                       not_ready = false;
+                       Row newrow(rowit->par(), z);
+                       rowit = rowlist_.insert(boost::next(rowit), newrow);
+               } else {
+                       done = true;
+               }
 
                // Set the dimensions of the row
                // fixed fill setting now by calling inset->update() in
                // SingleWidth when needed!
-               tmprow->fill(fill(*bview, *tmprow, workWidth(*bview)));
-               setHeightOfRow(bview, tmprow);
+               tmprow->fill(fill(tmprow, workWidth()));
+               setHeightOfRow(tmprow);
 
-       } while (not_ready);
+       } while (!done);
 }
 
 
-// Do we even need this at all ? Code that uses  RowPainter *already*
-// sets need_break_row when it sees a CHANGED_IN_DRAW, though not
-// quite like this
-void LyXText::markChangeInDraw(BufferView * bv, Row * row, Row * prev)
+void LyXText::breakAgain(RowList::iterator rit)
 {
-       if (prev && prev->par() == row->par()) {
-               breakAgainOneRow(bv, prev);
-               if (prev->next() != row) {
-                       // breakAgainOneRow() has removed row_
-                       need_break_row = prev;
-               } else {
-                       need_break_row = row;
-               }
-       } else if (!prev) {
-               need_break_row = firstrow;
-       } else {
-               need_break_row = prev->next();
-       }
-       setCursor(bv, cursor.par(), cursor.pos());
-       /* FIXME */
-}
+       Assert(rit != rows().end());
 
-
-void LyXText::breakAgain(BufferView * bview, Row * row) const
-{
        bool not_ready = true;
 
        do  {
-               // get the next breakpoint
-               pos_type z = nextBreakPoint(bview, row, workWidth(*bview));
-               Row * tmprow = row;
+               pos_type z = rowBreakPoint(*rit);
+               RowList::iterator tmprit = rit;
+               RowList::iterator end = rows().end();
 
-               if (z < row->par()->size()) {
-                       if (!row->next() || (row->next() && row->next()->par() != row->par())) {
+               if (z < rit->par()->size()) {
+                       RowList::iterator next_rit = boost::next(rit);
+
+                       if (next_rit == end ||
+                           (next_rit != end &&
+                            next_rit->par() != rit->par())) {
                                // insert a new row
                                ++z;
-                               insertRow(row, row->par(), z);
-                               row = row->next();
-                               row->height(0);
+                               Row newrow(rit->par(), z);
+                               rit = rowlist_.insert(next_rit, newrow);
                        } else  {
-                               row = row->next();
+                               ++rit;
                                ++z;
-                               if (row->pos() == z)
-                                       not_ready = false;     // the rest will not change
+                               if (rit->pos() == z)
+                                       not_ready = false; // the rest will not change
                                else {
-                                       row->pos(z);
+                                       rit->pos(z);
                                }
                        }
                } else {
                        // if there are some rows too much, delete them
                        // only if you broke the whole paragraph!
-                       Row * tmprow2 = row;
-                       while (tmprow2->next() && tmprow2->next()->par() == row->par()) {
-                               tmprow2 = tmprow2->next();
+                       RowList::iterator tmprit2 = rit;
+                       while (boost::next(tmprit2) != end
+                              && boost::next(tmprit2)->par() == rit->par()) {
+                               ++tmprit2;
                        }
-                       while (tmprow2 != row) {
-                               tmprow2 = tmprow2->previous();
-                               removeRow(tmprow2->next());
+                       while (tmprit2 != rit) {
+                               --tmprit2;
+                               removeRow(boost::next(tmprit2));
                        }
                        not_ready = false;
                }
 
                // set the dimensions of the row
-               tmprow->fill(fill(*bview, *tmprow, workWidth(*bview)));
-               setHeightOfRow(bview, tmprow);
+               tmprit->fill(fill(tmprit, workWidth()));
+               setHeightOfRow(tmprit);
        } while (not_ready);
 }
 
 
 // this is just a little changed version of break again
-void LyXText::breakAgainOneRow(BufferView * bview, Row * row)
+void LyXText::breakAgainOneRow(RowList::iterator rit)
 {
-       // get the next breakpoint
-       pos_type z = nextBreakPoint(bview, row, workWidth(*bview));
-       Row * tmprow = row;
+       Assert(rit != rows().end());
+
+       pos_type z = rowBreakPoint(*rit);
+       RowList::iterator tmprit = rit;
+       RowList::iterator end = rows().end();
+
+       if (z < rit->par()->size()) {
+               RowList::iterator next_rit = boost::next(rit);
 
-       if (z < row->par()->size()) {
-               if (!row->next()
-                   || (row->next() && row->next()->par() != row->par())) {
+               if (next_rit == end ||
+                   (next_rit != end &&
+                    next_rit->par() != rit->par())) {
                        // insert a new row
                        ++z;
-                       insertRow(row, row->par(), z);
-                       row = row->next();
-                       row->height(0);
+                       Row newrow(rit->par(), z);
+                       rit = rowlist_.insert(next_rit, newrow);
                } else  {
-                       row = row->next();
+                       ++rit;
                        ++z;
-                       if (row->pos() != z)
-                               row->pos(z);
+                       if (rit->pos() != z)
+                               rit->pos(z);
                }
        } else {
                // if there are some rows too much, delete them
                // only if you broke the whole paragraph!
-               Row * tmprow2 = row;
-               while (tmprow2->next()
-                      && tmprow2->next()->par() == row->par()) {
-                       tmprow2 = tmprow2->next();
+               RowList::iterator tmprit2 = rit;
+               while (boost::next(tmprit2) != end
+                      && boost::next(tmprit2)->par() == rit->par()) {
+                       ++tmprit2;
                }
-               while (tmprow2 != row) {
-                       tmprow2 = tmprow2->previous();
-                       removeRow(tmprow2->next());
+               while (tmprit2 != rit) {
+                       --tmprit2;
+                       removeRow(boost::next(tmprit2));
                }
        }
 
        // set the dimensions of the row
-       tmprow->fill(fill(*bview, *tmprow, workWidth(*bview)));
-       setHeightOfRow(bview, tmprow);
+       tmprit->fill(fill(tmprit, workWidth()));
+       setHeightOfRow(tmprit);
 }
 
 
-void LyXText::breakParagraph(BufferView * bview, char keep_layout)
+void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
 {
        // allow only if at start or end, or all previous is new text
        if (cursor.pos() && cursor.pos() != cursor.par()->size()
@@ -1332,17 +1462,16 @@ void LyXText::breakParagraph(BufferView * bview, char keep_layout)
                return;
 
        LyXTextClass const & tclass =
-               bview->buffer()->params.getLyXTextClass();
+               bv()->buffer()->params.getLyXTextClass();
        LyXLayout_ptr const & layout = cursor.par()->layout();
 
        // this is only allowed, if the current paragraph is not empty or caption
-       // and if it has not the keepempty flag aktive
-       if (cursor.par()->empty()
-          && layout->labeltype != LABEL_SENSITIVE
-          && !layout->keepempty)
+       // and if it has not the keepempty flag active
+       if (cursor.par()->empty() && !cursor.par()->allowEmpty()
+          && layout->labeltype != LABEL_SENSITIVE)
                return;
 
-       setUndo(bview, Undo::FINISH, cursor.par(), cursor.par()->next());
+       setUndo(bv(), Undo::FINISH, cursor.par());
 
        // Always break behind a space
        //
@@ -1362,8 +1491,8 @@ void LyXText::breakParagraph(BufferView * bview, char keep_layout)
        // breakParagraph call should return a bool if it inserts the
        // paragraph before or behind and we should react on that one
        // but we can fix this in 1.3.0 (Jug 20020509)
-       bool const isempty = (layout->keepempty && cursor.par()->empty());
-       ::breakParagraph(bview->buffer(), cursor.par(), cursor.pos(),
+       bool const isempty = (cursor.par()->allowEmpty() && cursor.par()->empty());
+       ::breakParagraph(bv()->buffer()->params, paragraphs, cursor.par(), cursor.pos(),
                       keep_layout);
 
        // well this is the caption hack since one caption is really enough
@@ -1373,81 +1502,87 @@ void LyXText::breakParagraph(BufferView * bview, char keep_layout)
                        cursor.par()->applyLayout(tclass.defaultLayout());
                else
                        // set to standard-layout
-                       cursor.par()->next()->applyLayout(tclass.defaultLayout());
+                       boost::next(cursor.par())->applyLayout(tclass.defaultLayout());
        }
 
        // if the cursor is at the beginning of a row without prior newline,
        // move one row up!
        // This touches only the screen-update. Otherwise we would may have
        // an empty row on the screen
-       if (cursor.pos() && !cursor.row()->par()->isNewline(cursor.row()->pos() - 1)
-                        && cursor.row()->pos() == cursor.pos())
+       if (cursor.pos() && cursorRow()->pos() == cursor.pos()
+           && !cursorRow()->par()->isNewline(cursor.pos() - 1))
        {
-               cursorLeft(bview);
+               cursorLeft(bv());
        }
 
-       status(bview, LyXText::NEED_MORE_REFRESH);
-       refresh_row = cursor.row();
-       refresh_y = cursor.y() - cursor.row()->baseline();
+       int y = cursor.y() - cursorRow()->baseline();
 
        // Do not forget the special right address boxes
        if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
-               while (refresh_row->previous() &&
-                      refresh_row->previous()->par() == refresh_row->par())
-               {
-                       refresh_row = refresh_row->previous();
-                       refresh_y -= refresh_row->height();
+               RowList::iterator r = cursorRow();
+               RowList::iterator beg = rows().begin();
+
+               while (r != beg && boost::prior(r)->par() == r->par()) {
+                       --r;
+                       y -= r->height();
                }
        }
-       removeParagraph(cursor.row());
+
+       postPaint(y);
+
+       removeParagraph(cursorRow());
 
        // set the dimensions of the cursor row
-       cursor.row()->fill(fill(*bview, *cursor.row(), workWidth(*bview)));
+       cursorRow()->fill(fill(cursorRow(), workWidth()));
 
-       setHeightOfRow(bview, cursor.row());
+       setHeightOfRow(cursorRow());
 
-       while (!cursor.par()->next()->empty()
-         && cursor.par()->next()->isNewline(0))
-          cursor.par()->next()->erase(0);
+#warning Trouble Point! (Lgb)
+       // When ::breakParagraph is called from within an inset we must
+       // ensure that the correct ParagraphList is used. Today that is not
+       // the case and the Buffer::paragraphs is used. Not good. (Lgb)
+       ParagraphList::iterator next_par = boost::next(cursor.par());
 
-       insertParagraph(bview, cursor.par()->next(), cursor.row());
+       while (!next_par->empty() && next_par->isNewline(0))
+               next_par->erase(0);
 
-       updateCounters(bview);
+       insertParagraph(next_par, boost::next(cursorRow()));
+       updateCounters();
 
        // This check is necessary. Otherwise the new empty paragraph will
        // be deleted automatically. And it is more friendly for the user!
        if (cursor.pos() || isempty)
-               setCursor(bview, cursor.par()->next(), 0);
+               setCursor(next_par, 0);
        else
-               setCursor(bview, cursor.par(), 0);
+               setCursor(cursor.par(), 0);
 
-       if (cursor.row()->next())
-               breakAgain(bview, cursor.row()->next());
+       if (boost::next(cursorRow()) != rows().end())
+               breakAgain(boost::next(cursorRow()));
 
-       need_break_row = 0;
+       need_break_row = rows().end();
 }
 
 
 // Just a macro to make some thing easier.
-void LyXText::redoParagraph(BufferView * bview) const
+void LyXText::redoParagraph()
 {
        clearSelection();
-       redoParagraphs(bview, cursor, cursor.par()->next());
-       setCursorIntern(bview, cursor.par(), cursor.pos());
+       redoParagraphs(cursor, boost::next(cursor.par()));
+       setCursorIntern(cursor.par(), cursor.pos());
 }
 
 
 // insert a character, moves all the following breaks in the
 // same Paragraph one to the right and make a rebreak
-void LyXText::insertChar(BufferView * bview, char c)
+void LyXText::insertChar(char c)
 {
-       setUndo(bview, Undo::INSERT, cursor.par(), cursor.par()->next());
+       setUndo(bv(), Undo::INSERT, cursor.par());
 
        // When the free-spacing option is set for the current layout,
        // disable the double-space checking
 
-       bool const freeSpacing = cursor.row()->par()->layout()->free_spacing ||
-               cursor.row()->par()->isFreeSpacing();
+       bool const freeSpacing = cursorRow()->par()->layout()->free_spacing ||
+               cursorRow()->par()->isFreeSpacing();
 
        if (lyxrc.auto_number) {
                static string const number_operators = "+-/*";
@@ -1459,17 +1594,17 @@ void LyXText::insertChar(BufferView * bview, char c)
                            !(contains(number_seperators, c) &&
                              cursor.pos() >= 1 &&
                              cursor.pos() < cursor.par()->size() &&
-                             getFont(bview->buffer(),
+                             getFont(bv()->buffer(),
                                      cursor.par(),
                                      cursor.pos()).number() == LyXFont::ON &&
-                             getFont(bview->buffer(),
+                             getFont(bv()->buffer(),
                                      cursor.par(),
                                      cursor.pos() - 1).number() == LyXFont::ON)
                           )
-                               number(bview); // Set current_font.number to OFF
+                               number(bv()); // Set current_font.number to OFF
                } else if (IsDigit(c) &&
                           real_current_font.isVisibleRightToLeft()) {
-                       number(bview); // Set current_font.number to ON
+                       number(bv()); // Set current_font.number to ON
 
                        if (cursor.pos() > 0) {
                                char const c = cursor.par()->getChar(cursor.pos() - 1);
@@ -1478,16 +1613,16 @@ void LyXText::insertChar(BufferView * bview, char c)
                                     cursor.par()->isSeparator(cursor.pos() - 2) ||
                                     cursor.par()->isNewline(cursor.pos() - 2))
                                  ) {
-                                       setCharFont(bview->buffer(),
+                                       setCharFont(bv()->buffer(),
                                                    cursor.par(),
                                                    cursor.pos() - 1,
                                                    current_font);
                                } else if (contains(number_seperators, c) &&
                                           cursor.pos() >= 2 &&
-                                          getFont(bview->buffer(),
+                                          getFont(bv()->buffer(),
                                                   cursor.par(),
                                                   cursor.pos() - 2).number() == LyXFont::ON) {
-                                       setCharFont(bview->buffer(),
+                                       setCharFont(bv()->buffer(),
                                                    cursor.par(),
                                                    cursor.pos() - 1,
                                                    current_font);
@@ -1516,7 +1651,7 @@ void LyXText::insertChar(BufferView * bview, char c)
        // Get the font that is used to calculate the baselineskip
        pos_type const lastpos = cursor.par()->size();
        LyXFont rawparfont =
-               cursor.par()->getFontSettings(bview->buffer()->params,
+               cursor.par()->getFontSettings(bv()->buffer()->params,
                                              lastpos - 1);
 
        bool jumped_over_space = false;
@@ -1530,99 +1665,89 @@ void LyXText::insertChar(BufferView * bview, char c)
                        static bool sent_space_message = false;
                        if (!sent_space_message) {
                                if (cursor.pos() == 0)
-                                       bview->owner()->message(_("You cannot insert a space at the beginning of a paragraph. Please read the Tutorial."));
+                                       bv()->owner()->message(_("You cannot insert a space at the beginning of a paragraph. Please read the Tutorial."));
                                else
-                                       bview->owner()->message(_("You cannot type two spaces this way. Please read the Tutorial."));
+                                       bv()->owner()->message(_("You cannot type two spaces this way. Please read the Tutorial."));
                                sent_space_message = true;
                        }
                        charInserted();
                        return;
                }
-       } else if (IsNewlineChar(c)) {
-               if (cursor.pos() <= cursor.par()->beginningOfMainBody()) {
-                       charInserted();
-                       return;
-               }
-               // No newline at first position of a paragraph or behind labels.
-               // TeX does not allow that
-
-               if (cursor.pos() < cursor.par()->size() &&
-                   cursor.par()->isLineSeparator(cursor.pos()))
-                       // newline always after a blank!
-                       cursorRight(bview);
-               cursor.row()->fill(-1);        // to force a new break
        }
 
        // the display inset stuff
-       if (cursor.row()->par()->isInset(cursor.row()->pos())) {
-               Inset * inset = cursor.row()->par()->getInset(cursor.row()->pos());
+       if (cursorRow()->pos() < cursorRow()->par()->size()
+           && cursorRow()->par()->isInset(cursorRow()->pos())) {
+               Inset * inset = cursorRow()->par()->getInset(cursorRow()->pos());
                if (inset && (inset->display() || inset->needFullRow())) {
                        // force a new break
-                       cursor.row()->fill(-1); // to force a new break
+                       cursorRow()->fill(-1); // to force a new break
                }
        }
 
        // get the cursor row fist
-       Row * row = cursor.row();
+       RowList::iterator row = cursorRow();
        int y = cursor.y() - row->baseline();
        if (c != Paragraph::META_INSET) {
                // Here case LyXText::InsertInset  already insertet the character
                cursor.par()->insertChar(cursor.pos(), c);
        }
-       setCharFont(bview->buffer(), cursor.par(), cursor.pos(), rawtmpfont);
+       setCharFont(bv()->buffer(), cursor.par(), cursor.pos(), rawtmpfont);
 
        if (!jumped_over_space) {
                // refresh the positions
-               Row * tmprow = row;
-               while (tmprow->next() && tmprow->next()->par() == row->par()) {
-                       tmprow = tmprow->next();
+               RowList::iterator tmprow = row;
+               while (boost::next(tmprow) != rows().end() &&
+                      boost::next(tmprow)->par() == row->par()) {
+                       ++tmprow;
                        tmprow->pos(tmprow->pos() + 1);
                }
        }
 
        // Is there a break one row above
-       if (row->previous() && row->previous()->par() == row->par()
+       if (row != rows().begin() &&
+           boost::prior(row)->par() == row->par()
            && (cursor.par()->isLineSeparator(cursor.pos())
                || cursor.par()->isNewline(cursor.pos())
-               || ((cursor.pos() < cursor.par()->size()) &&
-                   cursor.par()->isInset(cursor.pos()+1))
-               || cursor.row()->fill() == -1))
+               || ((cursor.pos() + 1 < cursor.par()->size()) &&
+                   cursor.par()->isInset(cursor.pos() + 1))
+               || cursorRow()->fill() == -1))
        {
-               pos_type z = nextBreakPoint(bview,
-                                                          row->previous(),
-                                                          workWidth(*bview));
+               pos_type z = rowBreakPoint(*boost::prior(row));
+
                if (z >= row->pos()) {
                        row->pos(z + 1);
 
                        // set the dimensions of the row above
-                       row->previous()->fill(fill(*bview,
-                                                  *row->previous(),
-                                                  workWidth(*bview)));
+                       boost::prior(row)->fill(fill(
+                                                  boost::prior(row),
+                                                  workWidth()));
+
+                       setHeightOfRow(boost::prior(row));
 
-                       setHeightOfRow(bview, row->previous());
+                       y -= boost::prior(row)->height();
 
-                       y -= row->previous()->height();
-                       refresh_y = y;
-                       refresh_row = row->previous();
-                       status(bview, LyXText::NEED_MORE_REFRESH);
+                       postPaint(y);
 
-                       breakAgainOneRow(bview, row);
+                       breakAgainOneRow(row);
 
                        current_font = rawtmpfont;
                        real_current_font = realtmpfont;
-                       setCursor(bview, cursor.par(), cursor.pos() + 1,
+                       setCursor(cursor.par(), cursor.pos() + 1,
                                  false, cursor.boundary());
                        // cursor MUST be in row now.
 
-                       if (row->next() && row->next()->par() == row->par())
-                               need_break_row = row->next();
+                       RowList::iterator next_row = boost::next(row);
+                       if (next_row != rows().end() &&
+                           next_row->par() == row->par())
+                               need_break_row = next_row;
                        else
-                               need_break_row = 0;
+                               need_break_row = rows().end();
 
                        // check, wether the last characters font has changed.
                        if (cursor.pos() && cursor.pos() == cursor.par()->size()
                            && rawparfont != rawtmpfont)
-                               redoHeightOfParagraph(bview, cursor);
+                               redoHeightOfParagraph();
 
                        charInserted();
                        return;
@@ -1633,60 +1758,70 @@ void LyXText::insertChar(BufferView * bview, char c)
        if (row->fill() >= 0) {
                // needed because a newline will set fill to -1. Otherwise
                // we would not get a rebreak!
-               row->fill(fill(*bview, *row, workWidth(*bview)));
+               row->fill(fill(row, workWidth()));
        }
 
        if (c == Paragraph::META_INSET || row->fill() < 0) {
-               refresh_y = y;
-               refresh_row = row;
-               status(bview, LyXText::NEED_MORE_REFRESH);
-               breakAgainOneRow(bview, row);
+               postPaint(y);
+               breakAgainOneRow(row);
+
+               RowList::iterator next_row = boost::next(row);
+
                // will the cursor be in another row now?
-               if (row->lastPos() <= cursor.pos() + 1 && row->next()) {
-                       if (row->next() && row->next()->par() == row->par())
+               if (lastPos(*this, row) <= cursor.pos() + 1 &&
+                   next_row != rows().end()) {
+                       if (next_row != rows().end() &&
+                           next_row->par() == row->par()) {
                                // this should always be true
-                               row = row->next();
-                       breakAgainOneRow(bview, row);
+                               ++row;
+                       }
+
+                       breakAgainOneRow(row);
                }
                current_font = rawtmpfont;
                real_current_font = realtmpfont;
 
-               setCursor(bview, cursor.par(), cursor.pos() + 1, false,
+               setCursor(cursor.par(), cursor.pos() + 1, false,
                          cursor.boundary());
-               if (isBoundary(bview->buffer(), cursor.par(), cursor.pos())
+               if (isBoundary(bv()->buffer(), *cursor.par(), cursor.pos())
                    != cursor.boundary())
-                       setCursor(bview, cursor.par(), cursor.pos(), false,
+                       setCursor(cursor.par(), cursor.pos(), false,
                          !cursor.boundary());
-               if (row->next() && row->next()->par() == row->par())
-                       need_break_row = row->next();
+
+               next_row = boost::next(row);
+
+               if (next_row != rows().end() &&
+                   next_row->par() == row->par())
+                       need_break_row = next_row;
                else
-                       need_break_row = 0;
+                       need_break_row = rows().end();
        } else {
-               refresh_y = y;
-               refresh_row = row;
-
+               // FIXME: similar code is duplicated all over - make resetHeightOfRow
                int const tmpheight = row->height();
-               setHeightOfRow(bview, row);
-               if (tmpheight == row->height())
-                       status(bview, LyXText::NEED_VERY_LITTLE_REFRESH);
-               else
-                       status(bview, LyXText::NEED_MORE_REFRESH);
+
+               setHeightOfRow(row);
+
+               if (tmpheight == row->height()) {
+                       postRowPaint(row, y);
+               } else {
+                       postPaint(y);
+               }
 
                current_font = rawtmpfont;
                real_current_font = realtmpfont;
-               setCursor(bview, cursor.par(), cursor.pos() + 1, false,
+               setCursor(cursor.par(), cursor.pos() + 1, false,
                          cursor.boundary());
        }
 
        // check, wether the last characters font has changed.
        if (cursor.pos() && cursor.pos() == cursor.par()->size()
            && rawparfont != rawtmpfont) {
-               redoHeightOfParagraph(bview, cursor);
+               redoHeightOfParagraph();
        } else {
                // now the special right address boxes
                if (cursor.par()->layout()->margintype
                    == MARGIN_RIGHT_ADDRESS_BOX) {
-                       redoDrawingOfParagraph(bview, cursor);
+                       redoDrawingOfParagraph(cursor);
                }
        }
 
@@ -1697,7 +1832,7 @@ void LyXText::insertChar(BufferView * bview, char c)
 void LyXText::charInserted()
 {
        // Here we could call FinishUndo for every 20 characters inserted.
-       // This is from my experience how emacs does it.
+       // This is from my experience how emacs does it. (Lgb)
        static unsigned int counter;
        if (counter < 20) {
                ++counter;
@@ -1708,45 +1843,52 @@ void LyXText::charInserted()
 }
 
 
-void LyXText::prepareToPrint(BufferView * bview,
-                            Row * row, float & x,
+void LyXText::prepareToPrint(RowList::iterator rit, float & x,
                             float & fill_separator,
                             float & fill_hfill,
                             float & fill_label_hfill,
                             bool bidi) const
 {
-       float nlh;
-       float ns;
-
-       float w = row->fill();
+       float w = rit->fill();
        fill_hfill = 0;
        fill_label_hfill = 0;
        fill_separator = 0;
        fill_label_hfill = 0;
 
+       ParagraphList::iterator pit = rit->par();
+
        bool const is_rtl =
-               row->par()->isRightToLeftPar(bview->buffer()->params);
+               pit->isRightToLeftPar(bv()->buffer()->params);
        if (is_rtl) {
-               x = (workWidth(*bview) > 0)
-                       ? rightMargin(*bview->buffer(), *row) : 0;
+               x = (workWidth() > 0)
+                       ? rightMargin(*bv()->buffer(), *rit) : 0;
        } else
-               x = (workWidth(*bview) > 0)
-                       ? leftMargin(bview, row) : 0;
+               x = (workWidth() > 0)
+                       ? leftMargin(*rit) : 0;
 
        // is there a manual margin with a manual label
-       LyXLayout_ptr const & layout = row->par()->layout();
+       LyXLayout_ptr const & layout = pit->layout();
 
        if (layout->margintype == MARGIN_MANUAL
            && layout->labeltype == LABEL_MANUAL) {
-               // one more since labels are left aligned
-               nlh = row->numberOfLabelHfills() + 1;
-               if (nlh && !row->par()->getLabelWidthString().empty()) {
-                       fill_label_hfill = labelFill(*bview, *row) / nlh;
+               /// We might have real hfills in the label part
+               float nlh = numberOfLabelHfills(*this, rit);
+
+               // A manual label par (e.g. List) has an auto-hfill
+               // between the label text and the body of the
+               // paragraph too.
+               // But we don't want to do this auto hfill if the par
+               // is empty.
+               if (!pit->empty())
+                       ++nlh;
+
+               if (nlh && !pit->getLabelWidthString().empty()) {
+                       fill_label_hfill = labelFill(*rit) / nlh;
                }
        }
 
        // are there any hfills in the row?
-       float const nh = row->numberOfHfills();
+       float const nh = numberOfHfills(*this, rit);
 
        if (nh) {
                if (w > 0)
@@ -1754,25 +1896,26 @@ void LyXText::prepareToPrint(BufferView * bview,
        // we don't have to look at the alignment if it is ALIGN_LEFT and
        // if the row is already larger then the permitted width as then
        // we force the LEFT_ALIGN'edness!
-       } else if (static_cast<int>(row->width()) < workWidth(*bview)) {
+       } else if (static_cast<int>(rit->width()) < workWidth()) {
                // is it block, flushleft or flushright?
                // set x how you need it
                int align;
-               if (row->par()->params().align() == LYX_ALIGN_LAYOUT) {
+               if (pit->params().align() == LYX_ALIGN_LAYOUT) {
                        align = layout->align;
                } else {
-                       align = row->par()->params().align();
+                       align = pit->params().align();
                }
 
                // center displayed insets
-               Inset * inset;
-               if (row->par()->isInset(row->pos())
-                   && (inset=row->par()->getInset(row->pos()))
+               Inset * inset = 0;
+               if (rit->pos() < pit->size()
+                   && pit->isInset(rit->pos())
+                   && (inset = pit->getInset(rit->pos()))
                    && (inset->display())) // || (inset->scroll() < 0)))
                    align = (inset->lyxCode() == Inset::MATHMACRO_CODE)
                        ? LYX_ALIGN_BLOCK : LYX_ALIGN_CENTER;
                // ERT insets should always be LEFT ALIGNED on screen
-               inset = row->par()->inInset();
+               inset = pit->inInset();
                if (inset && inset->owner() &&
                        inset->owner()->lyxCode() == Inset::ERT_CODE)
                {
@@ -1781,19 +1924,24 @@ void LyXText::prepareToPrint(BufferView * bview,
 
                switch (align) {
            case LYX_ALIGN_BLOCK:
-                       ns = row->numberOfSeparators();
-                       if (ns && row->next() && row->next()->par() == row->par() &&
-                           !(row->next()->par()->isNewline(row->next()->pos() - 1))
-                           && !(row->next()->par()->isInset(row->next()->pos())
-                                && row->next()->par()->getInset(row->next()->pos())
-                                && row->next()->par()->getInset(row->next()->pos())->display())
-                               )
-                       {
+           {
+                       float const ns = numberOfSeparators(*this, rit);
+                       RowList::iterator next_row = boost::next(rit);
+                       ParagraphList::iterator next_pit = next_row->par();
+
+                       if (ns && next_row != rowlist_.end() &&
+                           next_pit == pit &&
+                           !(next_pit->isNewline(next_row->pos() - 1))
+                           && !(next_pit->isInset(next_row->pos()) &&
+                                next_pit->getInset(next_row->pos()) &&
+                                next_pit->getInset(next_row->pos())->display())
+                               ) {
                                fill_separator = w / ns;
                        } else if (is_rtl) {
                                x += w;
                        }
                        break;
+           }
            case LYX_ALIGN_RIGHT:
                        x += w;
                        break;
@@ -1805,17 +1953,18 @@ void LyXText::prepareToPrint(BufferView * bview,
        if (!bidi)
                return;
 
-       computeBidiTables(bview->buffer(), row);
+       computeBidiTables(bv()->buffer(), rit);
        if (is_rtl) {
-               pos_type main_body = row->par()->beginningOfMainBody();
-               pos_type last = row->lastPos();
+               pos_type body_pos = pit->beginningOfBody();
+               pos_type last = lastPos(*this, rit);
 
-               if (main_body > 0 &&
-                   (main_body - 1 > last ||
-                    !row->par()->isLineSeparator(main_body - 1))) {
+               if (body_pos > 0 &&
+                   (body_pos - 1 > last ||
+                    !pit->isLineSeparator(body_pos - 1))) {
                        x += font_metrics::width(layout->labelsep,
-                                           getLabelFont(bview->buffer(), row->par()));
-                       if (main_body - 1 <= last)
+                                           getLabelFont(bv()->buffer(),
+                                                        pit));
+                       if (body_pos - 1 <= last)
                                x += fill_label_hfill;
                }
        }
@@ -1829,206 +1978,83 @@ void LyXText::prepareToPrint(BufferView * bview,
 // realize, that you left an empty paragraph, they will delete it.
 // They also delete the corresponding row
 
-void LyXText::cursorRightOneWord(BufferView * bview) const
+void LyXText::cursorRightOneWord()
 {
-       // treat floats, HFills and Insets as words
-       LyXCursor tmpcursor = cursor;
-       // CHECK See comment on top of text.C
-
-       if (tmpcursor.pos() == tmpcursor.par()->size()
-           && tmpcursor.par()->next()) {
-                       tmpcursor.par(tmpcursor.par()->next());
-                       tmpcursor.pos(0);
-       } else {
-               int steps = 0;
-
-               // Skip through initial nonword stuff.
-               while (tmpcursor.pos() < tmpcursor.par()->size() &&
-                      ! tmpcursor.par()->isWord(tmpcursor.pos())) {
-                 //    printf("Current pos1 %d", tmpcursor.pos()) ;
-                       tmpcursor.pos(tmpcursor.pos() + 1);
-                       ++steps;
-               }
-               // Advance through word.
-               while (tmpcursor.pos() < tmpcursor.par()->size() &&
-                       tmpcursor.par()->isWord(tmpcursor.pos())) {
-                 //     printf("Current pos2 %d", tmpcursor.pos()) ;
-                       tmpcursor.pos(tmpcursor.pos() + 1);
-                       ++steps;
-               }
-       }
-       setCursor(bview, tmpcursor.par(), tmpcursor.pos());
-}
-
-
-void LyXText::cursorTab(BufferView * bview) const
-{
-       LyXCursor tmpcursor = cursor;
-       while (tmpcursor.pos() < tmpcursor.par()->size()
-          && !tmpcursor.par()->isNewline(tmpcursor.pos()))
-       tmpcursor.pos(tmpcursor.pos() + 1);
-
-       if (tmpcursor.pos() == tmpcursor.par()->size()) {
-               if (tmpcursor.par()->next()) {
-                       tmpcursor.par(tmpcursor.par()->next());
-                       tmpcursor.pos(0);
-               }
-       } else
-               tmpcursor.pos(tmpcursor.pos() + 1);
-       setCursor(bview, tmpcursor.par(), tmpcursor.pos());
+       ::cursorRightOneWord(cursor, ownerParagraphs());
+       setCursor(cursor.par(), cursor.pos());
 }
 
 
 // Skip initial whitespace at end of word and move cursor to *start*
 // of prior word, not to end of next prior word.
-void LyXText::cursorLeftOneWord(BufferView * bview)  const
+void LyXText::cursorLeftOneWord()
 {
        LyXCursor tmpcursor = cursor;
-       cursorLeftOneWord(tmpcursor);
-       setCursor(bview, tmpcursor.par(), tmpcursor.pos());
-}
-
-
-void LyXText::cursorLeftOneWord(LyXCursor & cur) const
-{
-       // treat HFills, floats and Insets as words
-       cur = cursor;
-       while (cur.pos()
-              && (cur.par()->isSeparator(cur.pos() - 1)
-                  || cur.par()->isKomma(cur.pos() - 1))
-              && !(cur.par()->isHfill(cur.pos() - 1)
-                   || cur.par()->isInset(cur.pos() - 1)))
-               cur.pos(cur.pos() - 1);
-
-       if (cur.pos()
-           && (cur.par()->isInset(cur.pos() - 1)
-               || cur.par()->isHfill(cur.pos() - 1))) {
-               cur.pos(cur.pos() - 1);
-       } else if (!cur.pos()) {
-               if (cur.par()->previous()) {
-                       cur.par(cur.par()->previous());
-                       cur.pos(cur.par()->size());
-               }
-       } else {                // Here, cur != 0
-               while (cur.pos() > 0 &&
-                      cur.par()->isWord(cur.pos() - 1))
-                       cur.pos(cur.pos() - 1);
-       }
-}
-
-
-// Select current word. This depends on behaviour of
-// CursorLeftOneWord(), so it is patched as well.
-void LyXText::getWord(LyXCursor & from, LyXCursor & to,
-                     word_location const loc) const
-{
-       // first put the cursor where we wana start to select the word
-       from = cursor;
-       switch (loc) {
-       case WHOLE_WORD_STRICT:
-               if (cursor.pos() == 0 || cursor.pos() == cursor.par()->size()
-                   || cursor.par()->isSeparator(cursor.pos())
-                   || cursor.par()->isKomma(cursor.pos())
-                   || cursor.par()->isSeparator(cursor.pos() - 1)
-                   || cursor.par()->isKomma(cursor.pos() - 1)) {
-                       to = from;
-                       return;
-               }
-               // no break here, we go to the next
-
-       case WHOLE_WORD:
-               // Move cursor to the beginning, when not already there.
-               if (from.pos() && !from.par()->isSeparator(from.pos() - 1)
-                   && !from.par()->isKomma(from.pos() - 1))
-                       cursorLeftOneWord(from);
-               break;
-       case PREVIOUS_WORD:
-               // always move the cursor to the beginning of previous word
-               cursorLeftOneWord(from);
-               break;
-       case NEXT_WORD:
-               lyxerr << "LyXText::getWord: NEXT_WORD not implemented yet\n";
-               break;
-       case PARTIAL_WORD:
-               break;
-       }
-       to = from;
-       while (to.pos() < to.par()->size()
-              && !to.par()->isSeparator(to.pos())
-              && !to.par()->isKomma(to.pos())
-              && !to.par()->isHfill(to.pos())
-              && !to.par()->isInset(to.pos()))
-       {
-               to.pos(to.pos() + 1);
-       }
+       ::cursorLeftOneWord(tmpcursor, ownerParagraphs());
+       setCursor(tmpcursor.par(), tmpcursor.pos());
 }
 
 
-void LyXText::selectWord(BufferView * bview, word_location const loc)
+void LyXText::selectWord(word_location loc)
 {
-       LyXCursor from;
+       LyXCursor from = cursor;
        LyXCursor to;
-       getWord(from, to, loc);
+       ::getWord(from, to, loc, ownerParagraphs());
        if (cursor != from)
-               setCursor(bview, from.par(), from.pos());
+               setCursor(from.par(), from.pos());
        if (to == from)
                return;
        selection.cursor = cursor;
-       setCursor(bview, to.par(), to.pos());
-       setSelection(bview);
+       setCursor(to.par(), to.pos());
+       setSelection();
 }
 
 
 // Select the word currently under the cursor when no
 // selection is currently set
-bool LyXText::selectWordWhenUnderCursor(BufferView * bview,
-                                       word_location const loc)
+bool LyXText::selectWordWhenUnderCursor(word_location loc)
 {
        if (!selection.set()) {
-               selectWord(bview, loc);
+               selectWord(loc);
                return selection.set();
        }
        return false;
 }
 
 
-void LyXText::acceptChange(BufferView * bv)
+void LyXText::acceptChange()
 {
        if (!selection.set() && cursor.par()->size())
                return;
 
-       bv->hideCursor();
-
        if (selection.start.par() == selection.end.par()) {
                LyXCursor & startc = selection.start;
                LyXCursor & endc = selection.end;
-               setUndo(bv, Undo::INSERT, startc.par(), startc.par()->next());
+               setUndo(bv(), Undo::INSERT, startc.par());
                startc.par()->acceptChange(startc.pos(), endc.pos());
                finishUndo();
                clearSelection();
-               redoParagraphs(bv, startc, startc.par()->next());
-               setCursorIntern(bv, startc.par(), 0);
+               redoParagraphs(startc, boost::next(startc.par()));
+               setCursorIntern(startc.par(), 0);
        }
 #warning handle multi par selection
 }
 
 
-void LyXText::rejectChange(BufferView * bv)
+void LyXText::rejectChange()
 {
        if (!selection.set() && cursor.par()->size())
                return;
 
-       bv->hideCursor();
-
        if (selection.start.par() == selection.end.par()) {
                LyXCursor & startc = selection.start;
                LyXCursor & endc = selection.end;
-               setUndo(bv, Undo::INSERT, startc.par(), startc.par()->next());
+               setUndo(bv(), Undo::INSERT, startc.par());
                startc.par()->rejectChange(startc.pos(), endc.pos());
                finishUndo();
                clearSelection();
-               redoParagraphs(bv, startc, startc.par()->next());
-               setCursorIntern(bv, startc.par(), 0);
+               redoParagraphs(startc, boost::next(startc.par()));
+               setCursorIntern(startc.par(), 0);
        }
 #warning handle multi par selection
 }
@@ -2037,10 +2063,10 @@ void LyXText::rejectChange(BufferView * bv)
 // This function is only used by the spellchecker for NextWord().
 // It doesn't handle LYX_ACCENTs and probably never will.
 WordLangTuple const
-LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
+LyXText::selectNextWordToSpellcheck(float & value)
 {
        if (the_locking_inset) {
-               WordLangTuple word = the_locking_inset->selectNextWordToSpellcheck(bview, value);
+               WordLangTuple word = the_locking_inset->selectNextWordToSpellcheck(bv(), value);
                if (!word.word().empty()) {
                        value += float(cursor.y());
                        value /= float(height);
@@ -2048,43 +2074,43 @@ LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
                }
                // we have to go on checking so move cursor to the next char
                if (cursor.pos() == cursor.par()->size()) {
-                       if (!cursor.par()->next())
+                       if (boost::next(cursor.par()) == ownerParagraphs().end())
                                return word;
-                       cursor.par(cursor.par()->next());
+                       cursor.par(boost::next(cursor.par()));
                        cursor.pos(0);
                } else
                        cursor.pos(cursor.pos() + 1);
        }
-       Paragraph * tmppar = cursor.par();
+       ParagraphList::iterator tmppit = cursor.par();
 
        // If this is not the very first word, skip rest of
        // current word because we are probably in the middle
        // of a word if there is text here.
-       if (cursor.pos() || cursor.par()->previous()) {
+       if (cursor.pos() || cursor.par() != ownerParagraphs().begin()) {
                while (cursor.pos() < cursor.par()->size()
                       && cursor.par()->isLetter(cursor.pos()))
                        cursor.pos(cursor.pos() + 1);
        }
 
        // Now, skip until we have real text (will jump paragraphs)
-       while (1) {
-               Paragraph * cpar(cursor.par());
+       while (true) {
+               ParagraphList::iterator cpit = cursor.par();
                pos_type const cpos(cursor.pos());
 
-               if (cpos == cpar->size()) {
-                       if (cpar->next()) {
-                               cursor.par(cpar->next());
+               if (cpos == cpit->size()) {
+                       if (boost::next(cpit) != ownerParagraphs().end()) {
+                               cursor.par(boost::next(cpit));
                                cursor.pos(0);
                                continue;
                        }
                        break;
                }
 
-               bool const is_bad_inset(cpar->isInset(cpos)
-                       && !cpar->getInset(cpos)->allowSpellcheck());
+               bool const is_good_inset = cpit->isInset(cpos)
+                       && cpit->getInset(cpos)->allowSpellcheck();
 
-               if (cpar->isLetter(cpos) && !isDeletedText(*cpar, cpos)
-                       && !is_bad_inset)
+               if (!isDeletedText(*cpit, cpos)
+                   && (is_good_inset || cpit->isLetter(cpos)))
                        break;
 
                cursor.pos(cpos + 1);
@@ -2094,15 +2120,16 @@ LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
        if (cursor.pos() < cursor.par()->size() &&
            cursor.par()->isInset(cursor.pos())) {
                // lock the inset!
-               cursor.par()->getInset(cursor.pos())->edit(bview);
+               FuncRequest cmd(bv(), LFUN_INSET_EDIT, "left");
+               cursor.par()->getInset(cursor.pos())->localDispatch(cmd);
                // now call us again to do the above trick
                // but obviously we have to start from down below ;)
-               return bview->text->selectNextWordToSpellcheck(bview, value);
+               return bv()->text->selectNextWordToSpellcheck(value);
        }
 
        // Update the value if we changed paragraphs
-       if (cursor.par() != tmppar) {
-               setCursor(bview, cursor.par(), cursor.pos());
+       if (cursor.par() != tmppit) {
+               setCursor(cursor.par(), cursor.pos());
                value = float(cursor.y())/float(height);
        }
 
@@ -2110,7 +2137,7 @@ LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
        selection.cursor = cursor;
 
        string lang_code(
-               getFont(bview->buffer(), cursor.par(), cursor.pos())
+               getFont(bv()->buffer(), cursor.par(), cursor.pos())
                        .language()->code());
        // and find the end of the word (insets like optional hyphens
        // and ligature break are part of a word)
@@ -2133,14 +2160,14 @@ LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
 
 
 // This one is also only for the spellchecker
-void LyXText::selectSelectedWord(BufferView * bview)
+void LyXText::selectSelectedWord()
 {
        if (the_locking_inset) {
-               the_locking_inset->selectSelectedWord(bview);
+               the_locking_inset->selectSelectedWord(bv());
                return;
        }
        // move cursor to the beginning
-       setCursor(bview, selection.cursor.par(), selection.cursor.pos());
+       setCursor(selection.cursor.par(), selection.cursor.pos());
 
        // set the sel cursor
        selection.cursor = cursor;
@@ -2150,81 +2177,78 @@ void LyXText::selectSelectedWord(BufferView * bview)
               && (cursor.par()->isLetter(cursor.pos())))
                cursor.pos(cursor.pos() + 1);
 
-       setCursor(bview, cursor.par(), cursor.pos());
+       setCursor(cursor.par(), cursor.pos());
 
        // finally set the selection
-       setSelection(bview);
+       setSelection();
 }
 
 
 // Delete from cursor up to the end of the current or next word.
-void LyXText::deleteWordForward(BufferView * bview)
+void LyXText::deleteWordForward()
 {
        if (cursor.par()->empty())
-               cursorRight(bview);
+               cursorRight(bv());
        else {
                LyXCursor tmpcursor = cursor;
-               tmpcursor.row(0); // ??
                selection.set(true); // to avoid deletion
-               cursorRightOneWord(bview);
-               setCursor(bview, tmpcursor, tmpcursor.par(), tmpcursor.pos());
+               cursorRightOneWord();
+               setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos());
                selection.cursor = cursor;
                cursor = tmpcursor;
-               setSelection(bview);
+               setSelection();
 
                // Great, CutSelection() gets rid of multiple spaces.
-               cutSelection(bview, true, false);
+               cutSelection(true, false);
        }
 }
 
 
 // Delete from cursor to start of current or prior word.
-void LyXText::deleteWordBackward(BufferView * bview)
+void LyXText::deleteWordBackward()
 {
        if (cursor.par()->empty())
-               cursorLeft(bview);
+               cursorLeft(bv());
        else {
                LyXCursor tmpcursor = cursor;
-               tmpcursor.row(0); // ??
                selection.set(true); // to avoid deletion
-               cursorLeftOneWord(bview);
-               setCursor(bview, tmpcursor, tmpcursor.par(), tmpcursor.pos());
+               cursorLeftOneWord();
+               setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos());
                selection.cursor = cursor;
                cursor = tmpcursor;
-               setSelection(bview);
-               cutSelection(bview, true, false);
+               setSelection();
+               cutSelection(true, false);
        }
 }
 
 
 // Kill to end of line.
-void LyXText::deleteLineForward(BufferView * bview)
+void LyXText::deleteLineForward()
 {
        if (cursor.par()->empty())
                // Paragraph is empty, so we just go to the right
-               cursorRight(bview);
+               cursorRight(bv());
        else {
                LyXCursor tmpcursor = cursor;
                // We can't store the row over a regular setCursor
                // so we set it to 0 and reset it afterwards.
-               tmpcursor.row(0); // ??
                selection.set(true); // to avoid deletion
-               cursorEnd(bview);
-               setCursor(bview, tmpcursor, tmpcursor.par(), tmpcursor.pos());
+               cursorEnd();
+               setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos());
                selection.cursor = cursor;
                cursor = tmpcursor;
-               setSelection(bview);
+               setSelection();
                // What is this test for ??? (JMarc)
                if (!selection.set()) {
-                       deleteWordForward(bview);
+                       deleteWordForward();
                } else {
-                       cutSelection(bview, true, false);
+                       cutSelection(true, false);
                }
        }
 }
 
 
-void LyXText::changeCase(BufferView & bview, LyXText::TextCase action)
+void LyXText::changeCase(LyXText::TextCase action)
 {
        LyXCursor from;
        LyXCursor to;
@@ -2233,25 +2257,25 @@ void LyXText::changeCase(BufferView & bview, LyXText::TextCase action)
                from = selection.start;
                to = selection.end;
        } else {
-               getWord(from, to, PARTIAL_WORD);
-               setCursor(&bview, to.par(), to.pos() + 1);
+               from = cursor;
+               ::getWord(from, to, lyx::PARTIAL_WORD, ownerParagraphs());
+               setCursor(to.par(), to.pos() + 1);
        }
 
-       lyx::Assert(from <= to);
-
-       setUndo(&bview, Undo::FINISH, from.par(), to.par()->next());
+       setUndo(bv(), Undo::FINISH, from.par(), to.par());
 
        pos_type pos = from.pos();
-       Paragraph * par = from.par();
+       ParagraphList::iterator pit = from.par();
 
-       while (par && (pos != to.pos() || par != to.par())) {
-               if (pos == par->size()) {
-                       par = par->next();
+       while (pit != ownerParagraphs().end() &&
+              (pos != to.pos() || pit != to.par())) {
+               if (pos == pit->size()) {
+                       ++pit;
                        pos = 0;
                        continue;
                }
-               unsigned char c = par->getChar(pos);
-               if (!IsInsetChar(c) && !IsHfillChar(c)) {
+               unsigned char c = pit->getChar(pos);
+               if (!IsInsetChar(c)) {
                        switch (action) {
                        case text_lowercase:
                                c = lowercase(c);
@@ -2266,65 +2290,29 @@ void LyXText::changeCase(BufferView & bview, LyXText::TextCase action)
                        }
                }
 #warning changes
-               par->setChar(pos, c);
-               checkParagraph(&bview, par, pos);
+               pit->setChar(pos, c);
+               checkParagraph(pit, pos);
 
                ++pos;
        }
-       if (to.row() != from.row()) {
-               refresh_y = from.y() - from.row()->baseline();
-               refresh_row = from.row();
-               status(&bview, LyXText::NEED_MORE_REFRESH);
-       }
-}
-
-
-void LyXText::transposeChars(BufferView & bview)
-{
-       Paragraph * tmppar = cursor.par();
-
-       setUndo(&bview, Undo::FINISH, tmppar, tmppar->next());
-
-       pos_type tmppos = cursor.pos();
 
-       // First decide if it is possible to transpose at all
-
-       if (tmppos == 0 || tmppos == tmppar->size())
-               return;
-
-       if (isDeletedText(*tmppar, tmppos - 1)
-               || isDeletedText(*tmppar, tmppos))
-               return;
-
-       unsigned char c1 = tmppar->getChar(tmppos);
-       unsigned char c2 = tmppar->getChar(tmppos - 1);
-
-       // We should have an implementation that handles insets
-       // as well, but that will have to come later. (Lgb)
-       if (c1 == Paragraph::META_INSET || c2 == Paragraph::META_INSET)
-               return;
-
-       bool const erased = tmppar->erase(tmppos - 1, tmppos + 1);
-       pos_type const ipos(erased ? tmppos - 1 : tmppos + 1);
-
-       tmppar->insertChar(ipos, c1);
-       tmppar->insertChar(ipos + 1, c2);
-
-       checkParagraph(&bview, tmppar, tmppos);
+       if (getRow(to) != getRow(from))
+               postPaint(from.y() - getRow(from)->baseline());
 }
 
 
-void LyXText::Delete(BufferView * bview)
+void LyXText::Delete()
 {
        // this is a very easy implementation
 
        LyXCursor old_cursor = cursor;
        int const old_cur_par_id = old_cursor.par()->id();
-       int const old_cur_par_prev_id = old_cursor.par()->previous() ?
-               old_cursor.par()->previous()->id() : -1;
+       int const old_cur_par_prev_id =
+               (old_cursor.par() != ownerParagraphs().begin() ?
+                boost::prior(old_cursor.par())->id() : -1);
 
        // just move to the right
-       cursorRight(bview);
+       cursorRight(bv());
 
        // CHECK Look at the comment here.
        // This check is not very good...
@@ -2332,7 +2320,7 @@ void LyXText::Delete(BufferView * bview)
        // and that can very well delete the par or par->previous in
        // old_cursor. Will a solution where we compare paragraph id's
        //work better?
-       if ((cursor.par()->previous() ? cursor.par()->previous()->id() : -1)
+       if ((cursor.par() != ownerParagraphs().begin() ? boost::prior(cursor.par())->id() : -1)
            == old_cur_par_prev_id
            && cursor.par()->id() != old_cur_par_id) {
                // delete-empty-paragraph-mechanism has done it
@@ -2344,20 +2332,19 @@ void LyXText::Delete(BufferView * bview)
                LyXCursor tmpcursor = cursor;
                // to make sure undo gets the right cursor position
                cursor = old_cursor;
-               setUndo(bview, Undo::DELETE,
-                       cursor.par(), cursor.par()->next());
+               setUndo(bv(), Undo::DELETE, cursor.par());
                cursor = tmpcursor;
-               backspace(bview);
+               backspace();
        }
 }
 
 
-void LyXText::backspace(BufferView * bview)
+void LyXText::backspace()
 {
        // Get the font that is used to calculate the baselineskip
        pos_type lastpos = cursor.par()->size();
        LyXFont rawparfont =
-               cursor.par()->getFontSettings(bview->buffer()->params,
+               cursor.par()->getFontSettings(bv()->buffer()->params,
                                              lastpos - 1);
 
        if (cursor.pos() == 0) {
@@ -2378,47 +2365,46 @@ void LyXText::backspace(BufferView * bview)
                        // left and let the DeleteEmptyParagraphMechanism handle the actual deletion
                        // of the paragraph.
 
-                       if (cursor.par()->previous()) {
-                               Paragraph * tmppar = cursor.par()->previous();
-                               if (cursor.par()->layout() == tmppar->layout()
-                                   && cursor.par()->getAlign() == tmppar->getAlign()) {
+                       if (cursor.par() != ownerParagraphs().begin()) {
+                               ParagraphList::iterator tmppit = boost::prior(cursor.par());
+                               if (cursor.par()->layout() == tmppit->layout()
+                                   && cursor.par()->getAlign() == tmppit->getAlign()) {
                                        // Inherit bottom DTD from the paragraph below.
                                        // (the one we are deleting)
-                                       tmppar->params().lineBottom(cursor.par()->params().lineBottom());
-                                       tmppar->params().spaceBottom(cursor.par()->params().spaceBottom());
-                                       tmppar->params().pagebreakBottom(cursor.par()->params().pagebreakBottom());
+                                       tmppit->params().lineBottom(cursor.par()->params().lineBottom());
+                                       tmppit->params().spaceBottom(cursor.par()->params().spaceBottom());
+                                       tmppit->params().pagebreakBottom(cursor.par()->params().pagebreakBottom());
                                }
 
-                               cursorLeft(bview);
+                               cursorLeft(bv());
 
                                // the layout things can change the height of a row !
-                               int const tmpheight = cursor.row()->height();
-                               setHeightOfRow(bview, cursor.row());
-                               if (cursor.row()->height() != tmpheight) {
-                                       refresh_y = cursor.y() - cursor.row()->baseline();
-                                       refresh_row = cursor.row();
-                                       status(bview, LyXText::NEED_MORE_REFRESH);
+                               int const tmpheight = cursorRow()->height();
+                               setHeightOfRow(cursorRow());
+                               if (cursorRow()->height() != tmpheight) {
+                                       postPaint(cursor.y() - cursorRow()->baseline());
                                }
                                return;
                        }
                }
 
-               if (cursor.par()->previous()) {
-                       setUndo(bview, Undo::DELETE,
-                               cursor.par()->previous(), cursor.par()->next());
+               if (cursor.par() != ownerParagraphs().begin()) {
+                       setUndo(bv(), Undo::DELETE,
+                               boost::prior(cursor.par()),
+                               cursor.par());
                }
 
-               Paragraph * tmppar = cursor.par();
-               Row * tmprow = cursor.row();
+               ParagraphList::iterator tmppit = cursor.par();
+               RowList::iterator tmprow = cursorRow();
 
                // We used to do cursorLeftIntern() here, but it is
                // not a good idea since it triggers the auto-delete
                // mechanism. So we do a cursorLeftIntern()-lite,
                // without the dreaded mechanism. (JMarc)
-               if (cursor.par()->previous()) {
+               if (cursor.par() != ownerParagraphs().begin()) {
                        // steps into the above paragraph.
-                       setCursorIntern(bview, cursor.par()->previous(),
-                                       cursor.par()->previous()->size(),
+                       setCursorIntern(boost::prior(cursor.par()),
+                                       boost::prior(cursor.par())->size(),
                                        false);
                }
 
@@ -2432,15 +2418,15 @@ void LyXText::backspace(BufferView * bview)
 
                //      Correction: Pasting is always allowed with standard-layout
                LyXTextClass const & tclass =
-                       bview->buffer()->params.getLyXTextClass();
+                       bv()->buffer()->params.getLyXTextClass();
 
-               if (cursor.par() != tmppar
-                   && (cursor.par()->layout() == tmppar->layout()
-                       || tmppar->layout() == tclass.defaultLayout())
-                   && cursor.par()->getAlign() == tmppar->getAlign()) {
+               if (cursor.par() != tmppit
+                   && (cursor.par()->layout() == tmppit->layout()
+                       || tmppit->layout() == tclass.defaultLayout())
+                   && cursor.par()->getAlign() == tmppit->getAlign()) {
                        removeParagraph(tmprow);
                        removeRow(tmprow);
-                       mergeParagraph(bview->buffer(), cursor.par());
+                       mergeParagraph(bv()->buffer()->params, bv()->buffer()->paragraphs, cursor.par());
 
                        if (!cursor.pos() || !cursor.par()->isSeparator(cursor.pos() - 1))
                                ; //cursor.par()->insertChar(cursor.pos(), ' ');
@@ -2451,9 +2437,7 @@ void LyXText::backspace(BufferView * bview)
                                if (cursor.pos())
                                        cursor.pos(cursor.pos() - 1);
 
-                       status(bview, LyXText::NEED_MORE_REFRESH);
-                       refresh_row = cursor.row();
-                       refresh_y = cursor.y() - cursor.row()->baseline();
+                       postPaint(cursor.y() - cursorRow()->baseline());
 
                        // remove the lost paragraph
                        // This one is not safe, since the paragraph that the tmprow and the
@@ -2464,22 +2448,21 @@ void LyXText::backspace(BufferView * bview)
                        //RemoveRow(tmprow);
 
                        // This rebuilds the rows.
-                       appendParagraph(bview, cursor.row());
-                       updateCounters(bview);
+                       appendParagraph(cursorRow());
+                       updateCounters();
 
                        // the row may have changed, block, hfills etc.
-                       setCursor(bview, cursor.par(), cursor.pos(), false);
+                       setCursor(cursor.par(), cursor.pos(), false);
                }
        } else {
                // this is the code for a normal backspace, not pasting
                // any paragraphs
-               setUndo(bview, Undo::DELETE,
-                       cursor.par(), cursor.par()->next());
+               setUndo(bv(), Undo::DELETE, cursor.par());
                // We used to do cursorLeftIntern() here, but it is
                // not a good idea since it triggers the auto-delete
                // mechanism. So we do a cursorLeftIntern()-lite,
                // without the dreaded mechanism. (JMarc)
-               setCursorIntern(bview, cursor.par(), cursor.pos()- 1,
+               setCursorIntern(cursor.par(), cursor.pos()- 1,
                                false, cursor.boundary());
 
                if (cursor.par()->isInset(cursor.pos())) {
@@ -2488,19 +2471,19 @@ void LyXText::backspace(BufferView * bview)
                        if (cursor.par()->getInset(cursor.pos())->display() ||
                            cursor.par()->getInset(cursor.pos())->needFullRow()) {
                                cursor.par()->erase(cursor.pos());
-                               redoParagraph(bview);
+                               redoParagraph();
                                return;
                        }
                }
 
-               Row * row = cursor.row();
+               RowList::iterator row = cursorRow();
                int y = cursor.y() - row->baseline();
                pos_type z;
                // remember that a space at the end of a row doesnt count
                // when calculating the fill
-               if (cursor.pos() < row->lastPos() ||
+               if (cursor.pos() < lastPos(*this, row) ||
                    !cursor.par()->isLineSeparator(cursor.pos())) {
-                       row->fill(row->fill() + singleWidth(bview,
+                       row->fill(row->fill() + singleWidth(
                                                            cursor.par(),
                                                            cursor.pos()));
                }
@@ -2510,9 +2493,10 @@ void LyXText::backspace(BufferView * bview)
                if (cursor.pos() && cursor.par()->isNewline(cursor.pos())) {
                        cursor.par()->erase(cursor.pos());
                        // refresh the positions
-                       Row * tmprow = row;
-                       while (tmprow->next() && tmprow->next()->par() == row->par()) {
-                               tmprow = tmprow->next();
+                       RowList::iterator tmprow = row;
+                       while (boost::next(tmprow) != rows().end() &&
+                              boost::next(tmprow)->par() == row->par()) {
+                               ++tmprow;
                                tmprow->pos(tmprow->pos() - 1);
                        }
                        if (cursor.par()->isLineSeparator(cursor.pos() - 1))
@@ -2521,12 +2505,13 @@ void LyXText::backspace(BufferView * bview)
                        if (cursor.pos() < cursor.par()->size()
                            && !cursor.par()->isSeparator(cursor.pos())) {
                                cursor.par()->insertChar(cursor.pos(), ' ');
-                               setCharFont(bview->buffer(), cursor.par(),
+                               setCharFont(bv()->buffer(), cursor.par(),
                                            cursor.pos(), current_font);
                                // refresh the positions
                                tmprow = row;
-                               while (tmprow->next() && tmprow->next()->par() == row->par()) {
-                                       tmprow = tmprow->next();
+                               while (boost::next(tmprow) != rows().end() &&
+                                      boost::next(tmprow)->par() == row->par()) {
+                                       ++tmprow;
                                        tmprow->pos(tmprow->pos() + 1);
                                }
                        }
@@ -2534,335 +2519,248 @@ void LyXText::backspace(BufferView * bview)
                        cursor.par()->erase(cursor.pos());
 
                        // refresh the positions
-                       Row * tmprow = row;
-                       while (tmprow->next()
-                              && tmprow->next()->par() == row->par()) {
-                               tmprow = tmprow->next();
+                       RowList::iterator tmprow = row;
+                       while (boost::next(tmprow) != rows().end() &&
+                              boost::next(tmprow)->par() == row->par()) {
+                               ++tmprow;
                                tmprow->pos(tmprow->pos() - 1);
                        }
 
                        // delete newlines at the beginning of paragraphs
                        while (!cursor.par()->empty() &&
+                              cursor.pos() < cursor.par()->size() &&
                               cursor.par()->isNewline(cursor.pos()) &&
-                              cursor.pos() == cursor.par()->beginningOfMainBody()) {
+                              cursor.pos() == cursor.par()->beginningOfBody()) {
                                cursor.par()->erase(cursor.pos());
                                // refresh the positions
                                tmprow = row;
-                               while (tmprow->next() &&
-                                      tmprow->next()->par() == row->par()) {
-                                       tmprow = tmprow->next();
+                               while (boost::next(tmprow) != rows().end() &&
+                                      boost::next(tmprow)->par() == row->par()) {
+                                       ++tmprow;
                                        tmprow->pos(tmprow->pos() - 1);
                                }
                        }
                }
 
                // is there a break one row above
-               if (row->previous() && row->previous()->par() == row->par()) {
-                       z = nextBreakPoint(bview, row->previous(),
-                                          workWidth(*bview));
+               if (row != rows().begin() && boost::prior(row)->par() == row->par()) {
+                       z = rowBreakPoint(*boost::prior(row));
                        if (z >= row->pos()) {
                                row->pos(z + 1);
 
-                               Row * tmprow = row->previous();
+                               RowList::iterator tmprow = boost::prior(row);
 
                                // maybe the current row is now empty
                                if (row->pos() >= row->par()->size()) {
                                        // remove it
                                        removeRow(row);
-                                       need_break_row = 0;
+                                       need_break_row = rows().end();
                                } else {
-                                       breakAgainOneRow(bview, row);
-                                       if (row->next() && row->next()->par() == row->par())
-                                               need_break_row = row->next();
+                                       breakAgainOneRow(row);
+                                       if (boost::next(row) != rows().end() &&
+                                           boost::next(row)->par() == row->par())
+                                               need_break_row = boost::next(row);
                                        else
-                                               need_break_row = 0;
+                                               need_break_row = rows().end();
                                }
 
                                // set the dimensions of the row above
                                y -= tmprow->height();
-                               tmprow->fill(fill(*bview, *tmprow, workWidth(*bview)));
-                               setHeightOfRow(bview, tmprow);
+                               tmprow->fill(fill(tmprow, workWidth()));
+                               setHeightOfRow(tmprow);
 
-                               refresh_y = y;
-                               refresh_row = tmprow;
-                               status(bview, LyXText::NEED_MORE_REFRESH);
-                               setCursor(bview, cursor.par(), cursor.pos(),
+                               postPaint(y);
+
+                               setCursor(cursor.par(), cursor.pos(),
                                          false, cursor.boundary());
                                //current_font = rawtmpfont;
                                //real_current_font = realtmpfont;
                                // check, whether the last character's font has changed.
                                if (rawparfont !=
-                                   cursor.par()->getFontSettings(bview->buffer()->params,
+                                   cursor.par()->getFontSettings(bv()->buffer()->params,
                                                                  cursor.par()->size() - 1))
-                                       redoHeightOfParagraph(bview, cursor);
+                                       redoHeightOfParagraph();
                                return;
                        }
                }
 
                // break the cursor row again
-               if (row->next() && row->next()->par() == row->par() &&
-                   (row->lastPos() == row->par()->size() - 1 ||
-                    nextBreakPoint(bview, row, workWidth(*bview)) != row->lastPos())) {
+               if (boost::next(row) != rows().end() &&
+                   boost::next(row)->par() == row->par() &&
+                   (lastPos(*this, row) == row->par()->size() - 1 ||
+                    rowBreakPoint(*row) != lastPos(*this, row))) {
 
                        // it can happen that a paragraph loses one row
                        // without a real breakup. This is when a word
                        // is to long to be broken. Well, I don t care this
                        // hack ;-)
-                       if (row->lastPos() == row->par()->size() - 1)
-                               removeRow(row->next());
+                       if (lastPos(*this, row) == row->par()->size() - 1)
+                               removeRow(boost::next(row));
 
-                       refresh_y = y;
-                       refresh_row = row;
-                       status(bview, LyXText::NEED_MORE_REFRESH);
+                       postPaint(y);
 
-                       breakAgainOneRow(bview, row);
+                       breakAgainOneRow(row);
                        // will the cursor be in another row now?
-                       if (row->next() && row->next()->par() == row->par() &&
-                           row->lastPos() <= cursor.pos()) {
-                               row = row->next();
-                               breakAgainOneRow(bview, row);
+                       if (boost::next(row) != rows().end() &&
+                           boost::next(row)->par() == row->par() &&
+                           lastPos(*this, row) <= cursor.pos()) {
+                               ++row;
+                               breakAgainOneRow(row);
                        }
 
-                       setCursor(bview, cursor.par(), cursor.pos(), false, cursor.boundary());
+                       setCursor(cursor.par(), cursor.pos(), false, cursor.boundary());
 
-                       if (row->next() && row->next()->par() == row->par())
-                               need_break_row = row->next();
+                       if (boost::next(row) != rows().end() &&
+                           boost::next(row)->par() == row->par())
+                               need_break_row = boost::next(row);
                        else
-                               need_break_row = 0;
+                               need_break_row = rows().end();
                } else  {
                        // set the dimensions of the row
-                       row->fill(fill(*bview, *row, workWidth(*bview)));
+                       row->fill(fill(row, workWidth()));
                        int const tmpheight = row->height();
-                       setHeightOfRow(bview, row);
-                       if (tmpheight == row->height())
-                               status(bview, LyXText::NEED_VERY_LITTLE_REFRESH);
-                       else
-                               status(bview, LyXText::NEED_MORE_REFRESH);
-                       refresh_y = y;
-                       refresh_row = row;
-                       setCursor(bview, cursor.par(), cursor.pos(), false, cursor.boundary());
+                       setHeightOfRow(row);
+                       if (tmpheight == row->height()) {
+                               postRowPaint(row, y);
+                       } else {
+                               postPaint(y);
+                       }
+                       setCursor(cursor.par(), cursor.pos(), false, cursor.boundary());
                }
        }
 
        // current_font = rawtmpfont;
        // real_current_font = realtmpfont;
 
-       if (isBoundary(bview->buffer(), cursor.par(), cursor.pos())
+       if (isBoundary(bv()->buffer(), *cursor.par(), cursor.pos())
            != cursor.boundary())
-               setCursor(bview, cursor.par(), cursor.pos(), false,
+               setCursor(cursor.par(), cursor.pos(), false,
                          !cursor.boundary());
 
        lastpos = cursor.par()->size();
        if (cursor.pos() == lastpos)
-               setCurrentFont(bview);
+               setCurrentFont();
 
        // check, whether the last characters font has changed.
        if (rawparfont !=
-           cursor.par()->getFontSettings(bview->buffer()->params, lastpos - 1)) {
-               redoHeightOfParagraph(bview, cursor);
+           cursor.par()->getFontSettings(bv()->buffer()->params, lastpos - 1)) {
+               redoHeightOfParagraph();
        } else {
                // now the special right address boxes
                if (cursor.par()->layout()->margintype
                    == MARGIN_RIGHT_ADDRESS_BOX) {
-                       redoDrawingOfParagraph(bview, cursor);
+                       redoDrawingOfParagraph(cursor);
                }
        }
 }
 
 
-// returns the column near the specified x-coordinate of the row
-// x is set to the real beginning of this column
-pos_type
-LyXText::getColumnNearX(BufferView * bview, Row * row, int & x,
-                       bool & boundary) const
+RowList::iterator LyXText::cursorRow() const
 {
-       float tmpx = 0.0;
-       float fill_separator;
-       float fill_hfill;
-       float fill_label_hfill;
-
-       prepareToPrint(bview, row, tmpx, fill_separator,
-                      fill_hfill, fill_label_hfill);
-
-       pos_type vc = row->pos();
-       pos_type last = row->lastPrintablePos();
-       pos_type c = 0;
-
-       LyXLayout_ptr const & layout = row->par()->layout();
-
-       bool left_side = false;
-
-       pos_type main_body = row->par()->beginningOfMainBody();
-       float last_tmpx = tmpx;
-
-       if (main_body > 0 &&
-           (main_body - 1 > last ||
-            !row->par()->isLineSeparator(main_body - 1)))
-               main_body = 0;
-
-       // check for empty row
-       if (!row->par()->size()) {
-               x = int(tmpx);
-               return 0;
-       }
+       return getRow(cursor.par(), cursor.pos());
+}
 
-       while (vc <= last && tmpx <= x) {
-               c = vis2log(vc);
-               last_tmpx = tmpx;
-               if (main_body > 0 && c == main_body-1) {
-                       tmpx += fill_label_hfill +
-                               font_metrics::width(layout->labelsep,
-                                              getLabelFont(bview->buffer(), row->par()));
-                       if (row->par()->isLineSeparator(main_body - 1))
-                               tmpx -= singleWidth(bview, row->par(), main_body-1);
-               }
 
-               if (row->hfillExpansion(c)) {
-                       tmpx += singleWidth(bview, row->par(), c);
-                       if (c >= main_body)
-                               tmpx += fill_hfill;
-                       else
-                               tmpx += fill_label_hfill;
-               } else if (row->par()->isSeparator(c)) {
-                       tmpx += singleWidth(bview, row->par(), c);
-                       if (c >= main_body)
-                               tmpx+= fill_separator;
-               } else {
-                       tmpx += singleWidth(bview, row->par(), c);
-               }
-               ++vc;
-       }
-
-       if ((tmpx + last_tmpx) / 2 > x) {
-               tmpx = last_tmpx;
-               left_side = true;
-       }
+RowList::iterator LyXText::getRow(LyXCursor const & cur) const
+{
+       return getRow(cur.par(), cur.pos());
+}
 
-       if (vc > last + 1)  // This shouldn't happen.
-               vc = last + 1;
 
-       boundary = false;
-       bool const lastrow = lyxrc.rtl_support // This is not needed, but gives
-                                        // some speedup if rtl_support=false
-               && (!row->next() || row->next()->par() != row->par());
-       bool const rtl = (lastrow)
-               ? row->par()->isRightToLeftPar(bview->buffer()->params)
-               : false; // If lastrow is false, we don't need to compute
-                        // the value of rtl.
+RowList::iterator
+LyXText::getRow(ParagraphList::iterator pit, pos_type pos) const
+{
+       if (rows().empty())
+               return rowlist_.end();
 
-       if (lastrow &&
-                ((rtl &&  left_side && vc == row->pos() && x < tmpx - 5) ||
-                  (!rtl && !left_side && vc == last + 1   && x > tmpx + 5)))
-               c = last + 1;
-       else if (vc == row->pos()) {
-               c = vis2log(vc);
-               if (bidi_level(c) % 2 == 1)
-                       ++c;
-       } else {
-               c = vis2log(vc - 1);
-               bool const rtl = (bidi_level(c) % 2 == 1);
-               if (left_side == rtl) {
-                       ++c;
-                       boundary = isBoundary(bview->buffer(), row->par(), c);
-               }
+       // find the first row of the specified paragraph
+       RowList::iterator rit = rowlist_.begin();
+       RowList::iterator end = rowlist_.end();
+       while (boost::next(rit) != end && rit->par() != pit) {
+               ++rit;
        }
 
-       if (row->pos() <= last && c > last
-           && row->par()->isNewline(last)) {
-               if (bidi_level(last) % 2 == 0)
-                       tmpx -= singleWidth(bview, row->par(), last);
-               else
-                       tmpx += singleWidth(bview, row->par(), last);
-               c = last;
+       // now find the wanted row
+       while (rit->pos() < pos
+              && boost::next(rit) != end
+              && boost::next(rit)->par() == pit
+              && boost::next(rit)->pos() <= pos) {
+               ++rit;
        }
 
-       c -= row->pos();
-       x = int(tmpx);
-       return c;
+       return rit;
 }
 
-
 // returns pointer to a specified row
-Row * LyXText::getRow(Paragraph * par, pos_type pos, int & y) const
+RowList::iterator
+LyXText::getRow(ParagraphList::iterator pit, pos_type pos, int & y) const
 {
-       if (!firstrow)
-               return 0;
-
-       Row * tmprow = firstrow;
        y = 0;
 
+       if (rows().empty())
+               return rowlist_.end();
+
        // find the first row of the specified paragraph
-       while (tmprow->next() && tmprow->par() != par) {
-               y += tmprow->height();
-               tmprow = tmprow->next();
+       RowList::iterator rit = rowlist_.begin();
+       RowList::iterator end = rowlist_.end();
+       while (boost::next(rit) != end && rit->par() != pit) {
+               y += rit->height();
+               ++rit;
        }
 
        // now find the wanted row
-       while (tmprow->pos() < pos
-              && tmprow->next()
-              && tmprow->next()->par() == par
-              && tmprow->next()->pos() <= pos) {
-               y += tmprow->height();
-               tmprow = tmprow->next();
+       while (rit->pos() < pos
+              && boost::next(rit) != end
+              && boost::next(rit)->par() == pit
+              && boost::next(rit)->pos() <= pos) {
+               y += rit->height();
+               ++rit;
        }
 
-       return tmprow;
+       return rit;
 }
 
 
-Row * LyXText::getRowNearY(int & y) const
+RowList::iterator LyXText::getRowNearY(int & y) const
 {
-#if 1
-       // If possible we should optimize this method. (Lgb)
-       Row * tmprow = firstrow;
-       int tmpy = 0;
-
-       while (tmprow->next() && tmpy + tmprow->height() <= y) {
-               tmpy += tmprow->height();
-               tmprow = tmprow->next();
-       }
-
-       y = tmpy;   // return the real y
 
-       //lyxerr << "returned y = " << y << endl;
+       RowList::iterator rit = anchor_row_;
+       RowList::iterator const beg = rows().begin();
+       RowList::iterator const end = rows().end();
 
-       return tmprow;
-#else
-       // Search from the current cursor position.
-
-       Row * tmprow = cursor.row();
-       int tmpy = cursor.y() - tmprow->baseline();
-
-       lyxerr << "cursor.y() = " << tmpy << endl;
-       lyxerr << "tmprow->height() = " << tmprow->height() << endl;
-       lyxerr << "tmprow->baseline() = " << tmprow->baseline() << endl;
-       lyxerr << "first = " << first << endl;
-       lyxerr << "y = " << y << endl;
+       if (rows().empty()) {
+               y = 0;
+               return end;
+       }
+       if (rit == end)
+               rit = beg;
 
-       if (y < tmpy) {
-               lyxerr << "up" << endl;
-               do {
-                       tmpy -= tmprow->height();
-                       tmprow = tmprow->previous();
-               } while (tmprow && tmpy - tmprow->height() >= y);
-       } else if (y > tmpy) {
-               lyxerr << "down" << endl;
+       int tmpy = rit->y();
 
-               while (tmprow->next() && tmpy + tmprow->height() <= y) {
-                       tmpy += tmprow->height();
-                       tmprow = tmprow->next();
+       if (tmpy <= y) {
+               while (rit != end && tmpy <= y) {
+                       tmpy += rit->height();
+                       ++rit;
+               }
+               if (rit != beg) {
+                       --rit;
+                       tmpy -= rit->height();
                }
        } else {
-               lyxerr << "equal" << endl;
+               while (rit != beg && tmpy > y) {
+                       --rit;
+                       tmpy -= rit->height();
+               }
+       }
+       if (tmpy < 0 || rit == end) {
+               tmpy = 0;
+               rit = beg;
        }
 
-       y = tmpy; // return the real y
-
-       lyxerr << "returned y = " << y << endl;
-
-       return tmprow;
+       // return the rel y
+       y = tmpy;
 
-#endif
+       return rit;
 }