This adds an LCursor & argument to most of LyXText's cursor moving
functions. This simplifies logic in a few places and rids us from
using too much of the 'fishy' accesses (LyXText::cursorPar() & Co.)

I also shows that there are some dubious corners left. E.g. the 
LFUN_FLOAT_LIST handler seems to have accessed wrong cursor slices
since day one. Nothing big to fix, though....

Andre'

-- 
Those who desire to give up Freedom in order to gain Security, will not have,
nor do they deserve, either one.     (T. Jefferson or B. Franklin or both...)
Index: BufferView.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.C,v
retrieving revision 1.230
diff -u -p -r1.230 BufferView.C
--- BufferView.C        11 Feb 2004 14:45:37 -0000      1.230
+++ BufferView.C        12 Feb 2004 14:56:43 -0000
@@ -264,7 +264,7 @@ bool BufferView::insertLyXFile(string co
        string const fname = MakeAbsPath(filen);
 
        cursor().clearSelection();
-       text()->breakParagraph(buffer()->paragraphs());
+       text()->breakParagraph(cursor());
 
        bool res = buffer()->readFile(fname, text()->cursorPar());
        resize();
@@ -299,7 +299,9 @@ void BufferView::setCursorFromRow(int ro
        if (tmpid == -1)
                text()->setCursor(0, 0);
        else
-               text()->setCursor(buffer()->getParFromID(tmpid).pit(), tmppos);
+               text()->setCursor(
+                       text()->parOffset(buffer()->getParFromID(tmpid).pit()),
+                       tmppos);
 }
 
 
@@ -334,7 +336,7 @@ void BufferView::replaceWord(string cons
 
        // Go back so that replacement string is also spellchecked
        for (string::size_type i = 0; i < replacestring.length() + 1; ++i)
-               t->cursorLeft(this);
+               t->cursorLeft(cursor(), this);
 
        // FIXME: should be done through LFUN
        buffer()->markDirty();
@@ -417,7 +419,7 @@ void BufferView::setCursor(ParIterator c
                (*positions[i].it)->inset->edit(cur, true);
        cur.resetAnchor();
        LyXText * lt = par.text(*buffer());
-       lt->setCursor(par.pit(), pos);
+       lt->setCursor(lt->parOffset(par.pit()), pos);
 }
 
 
@@ -449,7 +451,7 @@ void BufferView::putSelectionAt(PosItera
        if (par.inset())
                top_y(par.outerPar()->y);
        update();
-       text->setCursor(cur.pit(), cur.pos());
+       text->setCursor(text->parOffset(cur.pit()), cur.pos());
        cursor().updatePos();
 
        if (length) {
Index: BufferView_pimpl.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v
retrieving revision 1.506
diff -u -p -r1.506 BufferView_pimpl.C
--- BufferView_pimpl.C  11 Feb 2004 14:45:38 -0000      1.506
+++ BufferView_pimpl.C  12 Feb 2004 14:56:43 -0000
@@ -684,7 +684,7 @@ void BufferView::Pimpl::restorePosition(
        if (par == buffer_->par_iterator_end())
                return;
 
-       bv_->text()->setCursor(par.pit(),
+       bv_->text()->setCursor(bv_->text()->parOffset(par.pit()),
                             min(par->size(), saved_positions[i].par_pos));
 
        if (i > 0)
@@ -1064,19 +1064,24 @@ bool BufferView::Pimpl::dispatch(FuncReq
        break;
 
        case LFUN_FLOAT_LIST:
+#warning Look here!
+               // Note that this seems to access the main lyx text only whereas the
+               // cursor stuff goes some possibly nested text. Would be good to
+               // make sure we are on the outermost level.
+
                if (tclass.floats().typeExist(cmd.argument)) {
                        InsetBase * inset = new InsetFloatList(cmd.argument);
                
                        // not quite sure if we want this...
-                       bv_->text()->recUndo(bv_->text()->cursor().par());
+                       bv_->text()->recUndo(bv_->cursor().par());
                        freezeUndo();
 
                        cur.clearSelection();
-                       bv_->text()->breakParagraph(bv_->buffer()->paragraphs());
+                       bv_->text()->breakParagraph(bv_->cursor());
 
                        if (!bv_->text()->cursorPar()->empty()) {
-                               bv_->text()->cursorLeft(true);
-                               
bv_->text()->breakParagraph(bv_->buffer()->paragraphs());
+                               bv_->text()->cursorLeft(bv_->cursor(), true);
+                               bv_->text()->breakParagraph(bv_->cursor());
                        }
 
                        bv_->text()->setLayout(tclass.defaultLayoutName());
Index: cursor.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.C,v
retrieving revision 1.54
diff -u -p -r1.54 cursor.C
--- cursor.C    11 Feb 2004 14:45:39 -0000      1.54
+++ cursor.C    12 Feb 2004 14:56:43 -0000
@@ -482,6 +482,18 @@ Paragraph const & LCursor::paragraph() c
 }
 
 
+Row & LCursor::textRow()
+{
+       return *paragraph().getRow(pos());
+}
+
+
+Row const & LCursor::textRow() const
+{
+       return *paragraph().getRow(pos());
+}
+
+
 LCursor::par_type LCursor::lastpar() const
 {
        return inMathed() ? 0 : text()->paragraphs().size() - 1;
Index: cursor.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.h,v
retrieving revision 1.32
diff -u -p -r1.32 cursor.h
--- cursor.h    11 Feb 2004 14:45:39 -0000      1.32
+++ cursor.h    12 Feb 2004 14:56:44 -0000
@@ -25,22 +25,20 @@ class FuncRequest;
 class InsetTabular;
 class LyXText;
 class Paragraph;
+class Row;
 
 
 // these should go
 class MathHullInset;
-class PainterInfo;
 class MathUnknownInset;
 class MathGridInset;
 
 
 // only needed for gcc 2.95, remove when support terminated
-
-
 template <typename A, typename B>
 bool ptr_cmp(A const * a, B const * b)
 {
-return a == b;
+       return a == b;
 }
 
 
@@ -218,14 +216,18 @@ public:
 
        //
        // text-specific part
-       ///
+       /// see comment for boundary_ below
        bool boundary() const { return current().boundary(); }
-       ///
+       /// see comment for boundary_ below
        bool & boundary() { return current().boundary(); }
-       ///
+       /// the paragraph we're in
        Paragraph & paragraph();
-       ///
+       /// the paragraph we're in
        Paragraph const & paragraph() const;
+       /// the row in the paragraph we're in
+       Row & textRow();
+       /// the row in the paragraph we're in
+       Row const & textRow() const;
        ///
        LyXText * text() const;
        ///
Index: lyxtext.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v
retrieving revision 1.288
diff -u -p -r1.288 lyxtext.h
--- lyxtext.h   11 Feb 2004 14:45:39 -0000      1.288
+++ lyxtext.h   12 Feb 2004 14:56:44 -0000
@@ -69,7 +69,7 @@ public:
                         LyXFont const & font, bool toggleall);
 
        /// what you expect when pressing <enter> at cursor position
-       void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
+       void breakParagraph(LCursor & cur, char keep_layout = 0);
 
        /** set layout over selection and make a total rebreak of
          those paragraphs
@@ -169,8 +169,6 @@ public:
        /// reject selected change
        void rejectChange();
 
-       ///
-       void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
        /// returns true if par was empty and was removed
        bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
                       bool setfont = true, bool boundary = false);
@@ -194,37 +192,37 @@ public:
        ///
        void edit(LCursor & cur, int x, int y);
        ///
-       void cursorUp(bool selecting = false);
+       void cursorUp(LCursor & cur, bool selecting = false);
        ///
-       void cursorDown(bool selecting = false);
+       void cursorDown(LCursor & cur, bool selecting = false);
        ///
-       bool cursorLeft(bool internal = true);
+       bool cursorLeft(LCursor & cur, bool internal = true);
        ///
-       bool cursorRight(bool internal = true);
+       bool cursorRight(LCursor & cur, bool internal = true);
        ///
-       void cursorLeftOneWord();
+       void cursorLeftOneWord(LCursor & cur);
        ///
-       void cursorRightOneWord();
+       void cursorRightOneWord(LCursor & cur);
        ///
-       void cursorUpParagraph();
+       void cursorUpParagraph(LCursor & cur);
        ///
-       void cursorDownParagraph();
+       void cursorDownParagraph(LCursor & cur);
        ///
-       void cursorHome();
+       void cursorHome(LCursor & cur);
        ///
-       void cursorEnd();
+       void cursorEnd(LCursor & cur);
        ///
-       void cursorPrevious();
+       void cursorPrevious(LCursor & cur);
        ///
-       void cursorNext();
+       void cursorNext(LCursor & cur);
        ///
-       void cursorTop();
+       void cursorTop(LCursor & cur);
        ///
-       void cursorBottom();
+       void cursorBottom(LCursor & cur);
        ///
-       void Delete();
+       void Delete(LCursor & cur);
        ///
-       void backspace();
+       void backspace(LCursor & cur);
        ///
        bool selectWordWhenUnderCursor(lyx::word_location);
        ///
@@ -342,27 +340,23 @@ public:
 
        ///
        double spacing(Paragraph const &) const;
-       ///
-       void cursorLeftOneWord(CursorSlice &);
-       ///
-       void cursorRightOneWord(CursorSlice &);
 
        ///
-       DispatchResult moveRight();
+       DispatchResult moveRight(LCursor & cur);
        ///
-       DispatchResult moveLeft();
+       DispatchResult moveLeft(LCursor & cur);
        ///
-       DispatchResult moveRightIntern(bool front,
+       DispatchResult moveRightIntern(LCursor & cur, bool front,
                bool activate_inset, bool selecting);
        ///
-       DispatchResult moveLeftIntern(bool front,
+       DispatchResult moveLeftIntern(LCursor & cur, bool front,
                bool activate_inset, bool selecting);
        ///
-       DispatchResult moveUp();
+       DispatchResult moveUp(LCursor & cur);
        ///
-       DispatchResult moveDown();
+       DispatchResult moveDown(LCursor & cur);
        ///
-       bool checkAndActivateInset(bool front);
+       bool checkAndActivateInset(LCursor & cur, bool front);
 
        ///
        void write(Buffer const & buf, std::ostream & os) const;
@@ -442,11 +436,11 @@ private:
        ///
        void setCounter(Buffer const &, ParagraphList::iterator pit);
        ///
-       void deleteWordForward();
+       void deleteWordForward(LCursor & cur);
        ///
-       void deleteWordBackward();
+       void deleteWordBackward(LCursor & cur);
        ///
-       void deleteLineForward();
+       void deleteLineForward(LCursor & cur);
 
        /// sets row.end to the pos value *after* which a row should break.
        /// for example, the pos after which isNewLine(pos) == true
Index: paragraph.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.C,v
retrieving revision 1.352
diff -u -p -r1.352 paragraph.C
--- paragraph.C 11 Feb 2004 14:45:39 -0000      1.352
+++ paragraph.C 12 Feb 2004 14:56:44 -0000
@@ -1830,6 +1830,18 @@ RowList::iterator Paragraph::getRow(pos_
 }
 
 
+RowList::const_iterator Paragraph::getRow(pos_type pos) const
+{
+       RowList::const_iterator rit = rows.end();
+       RowList::const_iterator const begin = rows.begin();
+
+       for (--rit; rit != begin && rit->pos() > pos; --rit)
+               ;
+
+       return rit;
+}
+
+
 size_t Paragraph::row(pos_type pos) const
 {
        RowList::const_iterator rit = rows.end();
Index: paragraph.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.h,v
retrieving revision 1.124
diff -u -p -r1.124 paragraph.h
--- paragraph.h 3 Feb 2004 08:56:23 -0000       1.124
+++ paragraph.h 12 Feb 2004 14:56:44 -0000
@@ -330,6 +330,8 @@ public:
        ///
        RowList::iterator getRow(lyx::pos_type pos);
        ///
+       RowList::const_iterator getRow(lyx::pos_type pos) const;
+       ///
        size_t row(lyx::pos_type pos) const;
 
        ///
Index: text.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text.C,v
retrieving revision 1.533
diff -u -p -r1.533 text.C
--- text.C      11 Feb 2004 14:45:40 -0000      1.533
+++ text.C      12 Feb 2004 14:56:44 -0000
@@ -752,31 +752,33 @@ void LyXText::setHeightOfRow(ParagraphLi
 }
 
 
-void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
+void LyXText::breakParagraph(LCursor & cur, char keep_layout)
 {
        // allow only if at start or end, or all previous is new text
-       ParagraphList::iterator cpit = cursorPar();
-       if (cursor().pos() && cursor().pos() != cpit->size()
-           && cpit->isChangeEdited(0, cursor().pos()))
+       Paragraph & cpar = cur.paragraph();
+       ParagraphList::iterator cpit = getPar(cur.par());
+
+       if (cur.pos() != 0 && cur.pos() != cur.lastpos()
+           && cpar.isChangeEdited(0, cur.pos()))
                return;
 
        LyXTextClass const & tclass =
                bv()->buffer()->params().getLyXTextClass();
-       LyXLayout_ptr const & layout = cpit->layout();
+       LyXLayout_ptr const & layout = cpar.layout();
 
        // this is only allowed, if the current paragraph is not empty
        // or caption and if it has not the keepempty flag active
-       if (cpit->empty() && !cpit->allowEmpty()
+       if (cur.lastpos() == 0 && !cpar.allowEmpty()
           && layout->labeltype != LABEL_SENSITIVE)
                return;
 
        // a layout change may affect also the following paragraph
-       recUndo(cursor().par(), parOffset(undoSpan(cpit)) - 1);
+       recUndo(cur.par(), parOffset(undoSpan(cpit)) - 1);
 
        // Always break behind a space
        // It is better to erase the space (Dekel)
-       if (cursor().pos() < cpit->size() && cpit->isLineSeparator(cursor().pos()))
-               cpit->erase(cursor().pos());
+       if (cur.pos() != cur.lastpos() && cpar.isLineSeparator(cur.pos()))
+               cpar.erase(cur.pos());
 
        // break the paragraph
        if (keep_layout)
@@ -788,16 +790,16 @@ void LyXText::breakParagraph(ParagraphLi
        // 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 = cpit->allowEmpty() && cpit->empty();
-       ::breakParagraph(bv()->buffer()->params(), paragraphs, cpit,
-                        cursor().pos(), keep_layout);
+       bool const isempty = cpar.allowEmpty() && cpar.empty();
+       ::breakParagraph(bv()->buffer()->params(), paragraphs(), cpit,
+                        cur.pos(), keep_layout);
 
-       cpit = cursorPar();
+       cpit = getPar(cur.par());
        ParagraphList::iterator next_par = boost::next(cpit);
 
        // well this is the caption hack since one caption is really enough
        if (layout->labeltype == LABEL_SENSITIVE) {
-               if (!cursor().pos())
+               if (!cur.pos())
                        // set to standard-layout
                        cpit->applyLayout(tclass.defaultLayout());
                else
@@ -809,11 +811,10 @@ void LyXText::breakParagraph(ParagraphLi
        // move one row up!
        // This touches only the screen-update. Otherwise we would may have
        // an empty row on the screen
-       RowList::iterator crit = cpit->getRow(cursor().pos());
-       if (cursor().pos() && crit->pos() == cursor().pos()
-           && !cpit->isNewline(cursor().pos() - 1))
+       if (cur.pos() != 0 && cur.textRow().pos() == cur.pos()
+           && !cpit->isNewline(cur.pos() - 1))
        {
-               cursorLeft(bv());
+               cursorLeft(cur, true);
        }
 
        while (!next_par->empty() && next_par->isNewline(0))
@@ -825,10 +826,10 @@ void LyXText::breakParagraph(ParagraphLi
 
        // 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(next_par, 0);
+       if (cur.pos() != 0 || isempty)
+               setCursor(cur.par() + 1, 0);
        else
-               setCursor(cpit, 0);
+               setCursor(cur.par(), 0);
 }
 
 
@@ -1080,20 +1081,53 @@ void LyXText::prepareToPrint(ParagraphLi
 // the cursor set functions have a special mechanism. When they
 // realize, that you left an empty paragraph, they will delete it.
 
-void LyXText::cursorRightOneWord()
+void LyXText::cursorRightOneWord(LCursor & cur)
 {
-       cursorRightOneWord(cursor());
-       setCursor(cursorPar(), cursor().pos());
+       // treat floats and insets as words
+       if (cur.pos() == cur.lastpos() && cur.par() != cur.lastpar()) {
+               ++cur.par();
+               cur.pos() = 0;
+       } else {
+               // Skip through initial nonword stuff.
+               while (cur.pos() != cur.lastpos() && 
!cur.paragraph().isWord(cur.pos())) {
+                       ++cur.pos();
+               }
+               // Advance through word.
+               while (cur.pos() != cur.lastpos() && 
cur.paragraph().isWord(cur.pos())) {
+                       ++cur.pos();
+               }
+       }
+       setCursor(cur.par(), cur.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()
+void LyXText::cursorLeftOneWord(LCursor & cur)
 {
-       CursorSlice tmpcursor = cursor();
-       cursorLeftOneWord(tmpcursor);
-       setCursor(getPar(tmpcursor), tmpcursor.pos());
+       // treat floats and insets as words
+       for ( ; cur.pos() != 0; --cur.pos()) {
+               Paragraph & par = cur.paragraph();
+               size_t pos = cur.pos() - 1;
+               if ((par.isSeparator(pos)
+                          || par.isKomma(pos)
+                          || par.isNewline(pos))
+                        &&
+              !par.isInset(pos))
+                       break;
+       }
+
+       if (cur.pos() != 0 && cur.prevInset() != 0) {
+               --cur.pos();
+       } else if (cur.pos() == 0) {
+               if (cur.par() != 0)
+                       --cur.par();
+       } else { // Here, cur.pos() != 0
+               while (cur.pos() && cur.paragraph().isWord(cur.pos() - 1))
+                       --cur.pos();
+       }
+
+       setCursor(cur.par(), cur.pos());
 }
 
 
@@ -1164,18 +1198,14 @@ void LyXText::rejectChange()
 
 
 // Delete from cursor up to the end of the current or next word.
-void LyXText::deleteWordForward()
+void LyXText::deleteWordForward(LCursor & cur)
 {
-       LCursor & cur = bv()->cursor();
-       if (cursorPar()->empty())
-               cursorRight(true);
+       if (cur.lastpos() == 0)
+               cursorRight(cur, true);
        else {
-               CursorSlice tmpcursor = cursor();
-               cur.selection() = true; // to avoid deletion
-               cursorRightOneWord();
-               setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos());
                cur.resetAnchor();
-               cursor() = tmpcursor;
+               cur.selection() = true;
+               cursorRightOneWord(cur);
                cur.setSelection();
                cutSelection(true, false);
        }
@@ -1183,18 +1213,14 @@ void LyXText::deleteWordForward()
 
 
 // Delete from cursor to start of current or prior word.
-void LyXText::deleteWordBackward()
+void LyXText::deleteWordBackward(LCursor & cur)
 {
-       LCursor & cur = bv()->cursor();
-       if (cursorPar()->empty())
-               cursorLeft(true);
+       if (cur.lastpos() == 0)
+               cursorLeft(cur, true);
        else {
-               CursorSlice tmpcursor = cursor();
-               cur.selection() = true; // to avoid deletion
-               cursorLeftOneWord();
-               setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos());
                cur.resetAnchor();
-               cursor() = tmpcursor;
+               cur.selection() = true;
+               cursorLeftOneWord(cur);
                cur.setSelection();
                cutSelection(true, false);
        }
@@ -1202,23 +1228,19 @@ void LyXText::deleteWordBackward()
 
 
 // Kill to end of line.
-void LyXText::deleteLineForward()
+void LyXText::deleteLineForward(LCursor & cur)
 {
-       LCursor & cur = bv()->cursor();
-       if (cursorPar()->empty()) {
+       if (cur.lastpos() == 0) {
                // Paragraph is empty, so we just go to the right
-               cursorRight(true);
+               cursorRight(cur, true);
        } else {
-               CursorSlice tmpcursor = cursor();
-               cur.selection() = true; // to avoid deletion
-               cursorEnd();
-               setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos());
                cur.resetAnchor();
-               cursor() = tmpcursor;
+               cur.selection() = true; // to avoid deletion
+               cursorEnd(cur);
                cur.setSelection();
                // What is this test for ??? (JMarc)
                if (!cur.selection())
-                       deleteWordForward();
+                       deleteWordForward(cur);
                else
                        cutSelection(true, false);
        }
@@ -1275,30 +1297,26 @@ void LyXText::changeCase(LyXText::TextCa
 }
 
 
-void LyXText::Delete()
+void LyXText::Delete(LCursor & cur)
 {
-       // this is a very easy implementation
-       CursorSlice old_cursor = cursor();
-
+       // this is a very simple implementation
        // just move to the right
-       cursorRight(true);
-
        // if you had success make a backspace
-       if (old_cursor.par() != cursor().par()
-           || old_cursor.pos() != cursor().pos()) {
-               recordUndo(bv()->cursor(), Undo::DELETE, old_cursor.par());
-               backspace();
+       size_t oldpar = cur.par();
+       if (cursorRight(cur, true)) {
+               recordUndo(cur, Undo::DELETE, oldpar);
+               backspace(cur);
        }
 }
 
 
-void LyXText::backspace()
+void LyXText::backspace(LCursor & cur)
 {
        // Get the font that is used to calculate the baselineskip
        ParagraphList::iterator pit = cursorPar();
        pos_type lastpos = pit->size();
 
-       if (cursor().pos() == 0) {
+       if (cur.pos() == 0) {
                // The cursor is at the beginning of a paragraph, so
                // the the backspace will collapse two paragraphs into
                // one.
@@ -1316,26 +1334,26 @@ void LyXText::backspace()
                        // left and let the DeleteEmptyParagraphMechanism
                        // handle the actual deletion of the paragraph.
 
-                       if (cursor().par()) {
-                               cursorLeft(bv());
+                       if (cur.par() != 0) {
+                               cursorLeft(cur, true);
                                // the layout things can change the height of a row !
                                redoParagraph();
                                return;
                        }
                }
 
-               if (cursor().par() != 0)
-                       recordUndo(bv()->cursor(), Undo::DELETE, cursor().par() - 1);
+               if (cur.par() != 0)
+                       recordUndo(cur, Undo::DELETE, cur.par() - 1);
 
                ParagraphList::iterator tmppit = cursorPar();
                // 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() != 0) {
+               if (cur.par() != 0) {
                        // steps into the above paragraph.
-                       setCursorIntern(cursor().par() - 1,
-                                       getPar(cursor().par() - 1)->size(),
+                       setCursorIntern(cur.par() - 1,
+                                       getPar(cur.par() - 1)->size(),
                                        false);
                }
 
@@ -1354,32 +1372,31 @@ void LyXText::backspace()
                    && cpit->getAlign() == tmppit->getAlign()) {
                        mergeParagraph(bufparams, buf.paragraphs(), cpit);
 
-                       if (cursor().pos() && cpit->isSeparator(cursor().pos() - 1))
-                               cursor().pos(cursor().pos() - 1);
+                       if (cur.pos() != 0 && cpit->isSeparator(cur.pos() - 1))
+                               --cur.pos();
 
                        // the counters may have changed
                        updateCounters();
-                       setCursor(cursor().par(), cursor().pos(), false);
+                       setCursor(cur.par(), cur.pos(), false);
                }
        } else {
                // this is the code for a normal backspace, not pasting
                // any paragraphs
-               recordUndo(bv()->cursor(), Undo::DELETE);
+               recordUndo(cur, Undo::DELETE);
                // 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(cursor().par(), cursor().pos() - 1,
-                               false, cursor().boundary());
-               cursorPar()->erase(cursor().pos());
+               setCursorIntern(cur.par(), cur.pos() - 1,
+                               false, cur.boundary());
+               cur.paragraph().erase(cur.pos());
        }
 
-       lastpos = cursorPar()->size();
-       if (cursor().pos() == lastpos)
+       if (cur.pos() == cur.lastpos())
                setCurrentFont();
 
        redoParagraph();
-       setCursor(cursor().par(), cursor().pos(), false, cursor().boundary());
+       setCursor(cur.par(), cur.pos(), false, cur.boundary());
 }
 
 
@@ -1599,7 +1616,7 @@ void LyXText::draw(PainterInfo & pi, int
 
 
 // only used for inset right now. should also be used for main text
-void LyXText::drawSelection(PainterInfo & pi, int x, int y) const
+void LyXText::drawSelection(PainterInfo &, int x, int y) const
 {
        lyxerr << "LyXText::drawSelection at " << x << " " << y << endl;
 }
@@ -1618,78 +1635,19 @@ bool LyXText::isFirstRow(ParagraphList::
 }
 
 
-void LyXText::cursorLeftOneWord(CursorSlice & cur)
-{
-       // treat HFills, floats and Insets as words
-
-       ParagraphList::iterator pit = cursorPar();
-       size_t pos = cur.pos();
-
-       while (pos &&
-              (pit->isSeparator(pos - 1) ||
-               pit->isKomma(pos - 1) ||
-               pit->isNewline(pos - 1)) &&
-              !(pit->isHfill(pos - 1) ||
-                pit->isInset(pos - 1)))
-               --pos;
-
-       if (pos &&
-           (pit->isInset(pos - 1) ||
-            pit->isHfill(pos - 1))) {
-               --pos;
-       } else if (!pos) {
-               if (pit != paragraphs().begin()) {
-                       --pit;
-                       pos = pit->size();
-               }
-       } else {                // Here, cur != 0
-               while (pos > 0 && pit->isWord(pos - 1))
-                       --pos;
-       }
-
-       cur.par(parOffset(pit));
-       cur.pos(pos);
-}
-
-
-void LyXText::cursorRightOneWord(CursorSlice & cur)
-{
-       // treat floats, HFills and Insets as words
-       ParagraphList::iterator pit = cursorPar();
-       pos_type pos = cur.pos();
-
-       if (pos == pit->size() &&
-               boost::next(pit) != paragraphs().end()) {
-               ++pit;
-               pos = 0;
-       } else {
-               // Skip through initial nonword stuff.
-               while (pos < pit->size() && !pit->isWord(pos)) {
-                       ++pos;
-               }
-               // Advance through word.
-               while (pos < pit->size() && pit->isWord(pos)) {
-                       ++pos;
-               }
-       }
-
-       cur.par(parOffset(pit));
-       cur.pos(pos);
-}
-
-
-void LyXText::getWord(CursorSlice & from, CursorSlice & to, word_location const loc)
+void LyXText::getWord(CursorSlice & from, CursorSlice & to,
+       word_location const loc)
 {
-       ParagraphList::iterator from_par = getPar(from);
+       Paragraph & from_par = *getPar(from);
        switch (loc) {
        case lyx::WHOLE_WORD_STRICT:
-               if (from.pos() == 0 || from.pos() == from_par->size()
-                   || from_par->isSeparator(from.pos())
-                   || from_par->isKomma(from.pos())
-                   || from_par->isNewline(from.pos())
-                   || from_par->isSeparator(from.pos() - 1)
-                   || from_par->isKomma(from.pos() - 1)
-                   || from_par->isNewline(from.pos() - 1)) {
+               if (from.pos() == 0 || from.pos() == from_par.size()
+                   || from_par.isSeparator(from.pos())
+                   || from_par.isKomma(from.pos())
+                   || from_par.isNewline(from.pos())
+                   || from_par.isSeparator(from.pos() - 1)
+                   || from_par.isKomma(from.pos() - 1)
+                   || from_par.isNewline(from.pos() - 1)) {
                        to = from;
                        return;
                }
@@ -1697,14 +1655,14 @@ void LyXText::getWord(CursorSlice & from
 
        case lyx::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)
-                        || from_par->isNewline(from.pos() - 1)))
-                       cursorLeftOneWord(from);
+               if (from.pos() && !from_par.isSeparator(from.pos() - 1)
+                   && !(from_par.isKomma(from.pos() - 1)
+                        || from_par.isNewline(from.pos() - 1)))
+                       cursorLeftOneWord(bv()->cursor());
                break;
        case lyx::PREVIOUS_WORD:
                // always move the cursor to the beginning of previous word
-               cursorLeftOneWord(from);
+               cursorLeftOneWord(bv()->cursor());
                break;
        case lyx::NEXT_WORD:
                lyxerr << "LyXText::getWord: NEXT_WORD not implemented yet"
@@ -1714,15 +1672,15 @@ void LyXText::getWord(CursorSlice & from
                break;
        }
        to = from;
-       ParagraphList::iterator to_par = getPar(to);
-       while (to.pos() < to_par->size()
-              && !to_par->isSeparator(to.pos())
-              && !to_par->isKomma(to.pos())
-              && !to_par->isNewline(to.pos())
-              && !to_par->isHfill(to.pos())
-              && !to_par->isInset(to.pos()))
+       Paragraph & to_par = *getPar(to);
+       while (to.pos() < to_par.size()
+              && !to_par.isSeparator(to.pos())
+              && !to_par.isKomma(to.pos())
+              && !to_par.isNewline(to.pos())
+              && !to_par.isHfill(to.pos())
+              && !to_par.isInset(to.pos()))
        {
-               to.pos(to.pos() + 1);
+               ++to.pos();
        }
 }
 
Index: text2.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v
retrieving revision 1.541
diff -u -p -r1.541 text2.C
--- text2.C     11 Feb 2004 14:45:42 -0000      1.541
+++ text2.C     12 Feb 2004 14:56:44 -0000
@@ -441,33 +441,30 @@ void LyXText::setFont(LyXFont const & fo
 // the cursor set functions have a special mechanism. When they
 // realize you left an empty paragraph, they will delete it.
 
-void LyXText::cursorHome()
+void LyXText::cursorHome(LCursor & cur)
 {
-       ParagraphList::iterator cpit = cursorPar();
-       setCursor(cpit, cpit->getRow(cursor().pos())->pos());
+       setCursor(cur.par(), cur.textRow().pos());
 }
 
 
-void LyXText::cursorEnd()
+void LyXText::cursorEnd(LCursor & cur)
 {
-       ParagraphList::iterator cpit = cursorPar();
-       pos_type end = cpit->getRow(cursor().pos())->endpos();
        // if not on the last row of the par, put the cursor before
        // the final space
-       setCursor(cpit, end == cpit->size() ? end : end - 1);
+       pos_type const end = cur.textRow().endpos();
+       setCursor(cur.par(), end == cur.lastpos() ? end : end - 1);
 }
 
 
-void LyXText::cursorTop()
+void LyXText::cursorTop(LCursor &)
 {
-       setCursor(paragraphs().begin(), 0);
+       setCursor(0, 0);
 }
 
 
-void LyXText::cursorBottom()
+void LyXText::cursorBottom(LCursor & cur)
 {
-       ParagraphList::iterator lastpit = boost::prior(paragraphs().end());
-       setCursor(lastpit, lastpit->size());
+       setCursor(cur.lastpar(), boost::prior(paragraphs().end())->size());
 }
 
 
@@ -878,7 +875,7 @@ void LyXText::insertInset(InsetBase * in
        // and fails if the cursor is behind the inset and getInset
        // does not return the inset!
        if (isHighlyEditableInset(inset))
-               cursorLeft(true);
+               cursorLeft(bv()->cursor(), true);
 
        unFreezeUndo();
 }
@@ -997,7 +994,7 @@ void LyXText::pasteSelection(size_t sel_
 
        cur.clearSelection();
        cur.resetAnchor();
-       setCursor(ppp.first, ppp.second);
+       setCursor(parOffset(ppp.first), ppp.second);
        cur.setSelection();
        updateCounters();
 }
@@ -1011,7 +1008,7 @@ void LyXText::setSelectionRange(lyx::pos
        LCursor & cur = bv()->cursor();
        cur.resetAnchor();
        while (length--)
-               cursorRight(true);
+               cursorRight(cur, true);
        cur.setSelection();
 }
 
@@ -1059,7 +1056,7 @@ void LyXText::insertStringAsLines(string
 
        redoParagraphs(cursorPar(), endpit);
        cur.resetAnchor();
-       setCursor(pit, pos);
+       setCursor(parOffset(pit), pos);
        cur.setSelection();
 }
 
@@ -1092,12 +1089,6 @@ void LyXText::insertStringAsParagraphs(s
 }
 
 
-void LyXText::setCursor(ParagraphList::iterator pit, pos_type pos)
-{
-       setCursor(parOffset(pit), pos);
-}
-
-
 bool LyXText::setCursor(paroffset_type par, pos_type pos, bool setfont,
        bool boundary)
 {
@@ -1363,91 +1354,87 @@ void LyXText::edit(LCursor & cur, int x,
 }
 
 
-bool LyXText::checkAndActivateInset(bool front)
+bool LyXText::checkAndActivateInset(LCursor & cur, bool front)
 {
-       if (cursor().pos() == cursorPar()->size())
+       if (cur.pos() == cur.lastpos())
                return false;
-       InsetBase * inset = cursorPar()->getInset(cursor().pos());
+       InsetBase * inset = cur.nextInset();
        if (!isHighlyEditableInset(inset))
                return false;
-       inset->edit(bv()->cursor(), front);
+       inset->edit(cur, front);
        return true;
 }
 
 
-DispatchResult LyXText::moveRight()
+DispatchResult LyXText::moveRight(LCursor & cur)
 {
-       if (cursorPar()->isRightToLeftPar(bv()->buffer()->params()))
-               return moveLeftIntern(false, true, false);
+       if (cur.paragraph().isRightToLeftPar(bv()->buffer()->params()))
+               return moveLeftIntern(cur, false, true, false);
        else
-               return moveRightIntern(true, true, false);
+               return moveRightIntern(cur, true, true, false);
 }
 
 
-DispatchResult LyXText::moveLeft()
+DispatchResult LyXText::moveLeft(LCursor & cur)
 {
-       if (cursorPar()->isRightToLeftPar(bv()->buffer()->params()))
-               return moveRightIntern(true, true, false);
+       if (cur.paragraph().isRightToLeftPar(bv()->buffer()->params()))
+               return moveRightIntern(cur, true, true, false);
        else
-               return moveLeftIntern(false, true, false);
+               return moveLeftIntern(cur, false, true, false);
 }
 
 
-DispatchResult LyXText::moveRightIntern(bool front, bool activate_inset, bool 
selecting)
+DispatchResult LyXText::moveRightIntern(LCursor & cur, 
+       bool front, bool activate_inset, bool selecting)
 {
-       ParagraphList::iterator c_par = cursorPar();
-       if (boost::next(c_par) == paragraphs().end()
-               && cursor().pos() >= c_par->size())
+       if (cur.par() == cur.lastpar() && cur.pos() == cur.lastpos())
                return DispatchResult(false, FINISHED_RIGHT);
-       if (activate_inset && checkAndActivateInset(front))
+       if (activate_inset && checkAndActivateInset(cur, front))
                return DispatchResult(true, true);
-       cursorRight(true);
+       cursorRight(cur, true);
        if (!selecting)
-               bv()->cursor().clearSelection();
+               cur.clearSelection();
        return DispatchResult(true);
 }
 
 
-DispatchResult LyXText::moveLeftIntern(bool front,
-                         bool activate_inset, bool selecting)
+DispatchResult LyXText::moveLeftIntern(LCursor & cur,
+       bool front, bool activate_inset, bool selecting)
 {
-       if (cursor().par() == 0 && cursor().pos() <= 0)
+       if (cur.par() == 0 && cur.pos() == 0)
                return DispatchResult(false, FINISHED);
-       cursorLeft(true);
+       cursorLeft(cur, true);
        if (!selecting)
-               bv()->cursor().clearSelection();
-       if (activate_inset && checkAndActivateInset(front))
+               cur.clearSelection();
+       if (activate_inset && checkAndActivateInset(cur, front))
                return DispatchResult(true, true);
        return DispatchResult(true);
 }
 
 
-DispatchResult LyXText::moveUp()
+DispatchResult LyXText::moveUp(LCursor & cur)
 {
-       LCursor & cur = bv()->cursor();
-       if (cur.par() == 0 && cursorRow() == firstRow())
+       if (cur.par() == 0 && cur.row() == 0)
                return DispatchResult(false, FINISHED_UP);
-       cursorUp(false);
+       cursorUp(cur, false);
        cur.clearSelection();
        return DispatchResult(true);
 }
 
 
-DispatchResult LyXText::moveDown()
+DispatchResult LyXText::moveDown(LCursor & cur)
 {
-       LCursor & cur = bv()->cursor();
-       if (cur.par() == cur.lastpar() && cursorRow() == lastRow())
+       if (cur.par() == cur.lastpar() && cur.textRow().endpos() == cur.lastpos())
                return DispatchResult(false, FINISHED_DOWN);
-       cursorDown(false);
+       cursorDown(cur, false);
        cur.clearSelection();
        return DispatchResult(true);
 }
 
 
-bool LyXText::cursorLeft(bool internal)
+bool LyXText::cursorLeft(LCursor & cur, bool internal)
 {
-       LCursor & cur = bv()->cursor();
-       if (cur.pos() > 0) {
+       if (cur.pos() != 0) {
                bool boundary = cur.boundary();
                setCursor(cur.par(), cur.pos() - 1, true, false);
                if (!internal && !boundary &&
@@ -1466,9 +1453,8 @@ bool LyXText::cursorLeft(bool internal)
 }
 
 
-bool LyXText::cursorRight(bool internal)
+bool LyXText::cursorRight(LCursor & cur, bool internal)
 {
-       LCursor & cur = bv()->cursor();
        if (!internal && cur.boundary()) {
                setCursor(cur.par(), cur.pos(), true, false);
                return true;
@@ -1482,7 +1468,7 @@ bool LyXText::cursorRight(bool internal)
                return true;
        }
 
-       if (cur.par() + 1 != int(paragraphs().size())) {
+       if (cur.par() != cur.lastpar()) {
                setCursor(cur.par() + 1, 0);
                return true;
        }
@@ -1491,9 +1477,8 @@ bool LyXText::cursorRight(bool internal)
 }
 
 
-void LyXText::cursorUp(bool selecting)
+void LyXText::cursorUp(LCursor & cur, bool selecting)
 {
-       LCursor & cur = bv()->cursor();
        Row const & row = *cursorRow();
        int x = cur.x_target();
        int y = cursorY(cur.current()) - row.baseline() - 1;
@@ -1507,13 +1492,12 @@ void LyXText::cursorUp(bool selecting)
 }
 
 
-void LyXText::cursorDown(bool selecting)
+void LyXText::cursorDown(LCursor & cur, bool selecting)
 {
-       LCursor & cur = bv()->cursor();
-       Row const & row = *cursorRow();
+       Row const & row = cur.textRow();
        int x = cur.x_target();
        int y = cursorY(cur.current()) - row.baseline() + row.height() + 1;
-       setCursorFromCoordinates(x, y);
+       setCursorFromCoordinates(cur.current(), x, y);
 
        if (!selecting) {
                InsetBase * inset_hit = checkInsetHit(cur.x_target(), y);
@@ -1523,25 +1507,21 @@ void LyXText::cursorDown(bool selecting)
 }
 
 
-void LyXText::cursorUpParagraph()
+void LyXText::cursorUpParagraph(LCursor & cur)
 {
-       ParagraphList::iterator cpit = cursorPar();
-       if (cursor().pos() > 0)
-               setCursor(cpit, 0);
-       else if (cpit != paragraphs().begin())
-               setCursor(boost::prior(cpit), 0);
+       if (cur.pos() > 0)
+               setCursor(cur.par(), 0);
+       else if (cur.par() != 0)
+               setCursor(cur.par() - 1, 0);
 }
 
 
-void LyXText::cursorDownParagraph()
+void LyXText::cursorDownParagraph(LCursor & cur)
 {
-       ParagraphList::iterator pit = cursorPar();
-       ParagraphList::iterator next_pit = boost::next(pit);
-
-       if (next_pit != paragraphs().end())
-               setCursor(next_pit, 0);
+       if (cur.par() != cur.lastpar())
+               setCursor(cur.par() + 1, 0);
        else
-               setCursor(pit, pit->size());
+               setCursor(cur.par(), cur.lastpos());
 }
 
 
@@ -1557,7 +1537,7 @@ void LyXText::fixCursorAfterDelete(Curso
        // if cursor position is after the place where the delete occured,
        // update it
        if (cur.pos() > where.pos())
-               cur.pos(cur.pos()-1);
+               --cur.pos();
 
        // check also if we don't want to set the cursor on a spot behind the
        // pagragraph because we erased the last character.
Index: text3.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v
retrieving revision 1.220
diff -u -p -r1.220 text3.C
--- text3.C     11 Feb 2004 14:45:42 -0000      1.220
+++ text3.C     12 Feb 2004 14:56:44 -0000
@@ -286,20 +286,19 @@ void LyXText::gotoInset(InsetOld_code co
 }
 
 
-void LyXText::cursorPrevious()
+void LyXText::cursorPrevious(LCursor & cur)
 {
-       LCursor & cur = bv()->cursor();
        pos_type cpos = cur.pos();
        lyx::paroffset_type cpar = cur.par();
 
-       int x = bv()->cursor().x_target();
+       int x = cur.x_target();
        int y = bv()->top_y();
        setCursorFromCoordinates(x, y);
 
        if (cpar == cur.par() && cpos == cur.pos()) {
                // we have a row which is taller than the workarea. The
                // simplest solution is to move to the previous row instead.
-               cursorUp(true);
+               cursorUp(cur, true);
        }
 
        bv()->updateScrollbar();
@@ -307,9 +306,8 @@ void LyXText::cursorPrevious()
 }
 
 
-void LyXText::cursorNext()
+void LyXText::cursorNext(LCursor & cur)
 {
-       LCursor & cur = bv()->cursor();
        pos_type cpos = cur.pos();
        lyx::paroffset_type cpar = cur.par();
 
@@ -320,7 +318,7 @@ void LyXText::cursorNext()
        if (cpar == cur.par() && cpos == cur.pos()) {
                // we have a row which is taller than the workarea. The
                // simplest solution is to move to the next row instead.
-               cursorDown(true);
+               cursorDown(cur, true);
        }
 
        bv()->updateScrollbar();
@@ -413,19 +411,19 @@ DispatchResult LyXText::dispatch(LCursor
 
        case LFUN_DELETE_WORD_FORWARD:
                cur.clearSelection();
-               deleteWordForward();
+               deleteWordForward(cur);
                finishChange(cur);
                break;
 
        case LFUN_DELETE_WORD_BACKWARD:
                cur.clearSelection();
-               deleteWordBackward();
+               deleteWordBackward(cur);
                finishChange(cur);
                break;
 
        case LFUN_DELETE_LINE_FORWARD:
                cur.clearSelection();
-               deleteLineForward();
+               deleteLineForward(cur);
                finishChange(cur);
                break;
 
@@ -433,9 +431,9 @@ DispatchResult LyXText::dispatch(LCursor
                if (!cur.mark())
                        cur.clearSelection();
                if (rtl())
-                       cursorLeftOneWord();
+                       cursorLeftOneWord(cur);
                else
-                       cursorRightOneWord();
+                       cursorRightOneWord(cur);
                finishChange(cur);
                break;
 
@@ -443,23 +441,23 @@ DispatchResult LyXText::dispatch(LCursor
                if (!cur.mark())
                        cur.clearSelection();
                if (rtl())
-                       cursorRightOneWord();
+                       cursorRightOneWord(cur);
                else
-                       cursorLeftOneWord();
+                       cursorLeftOneWord(cur);
                finishChange(cur);
                break;
 
        case LFUN_BEGINNINGBUF:
                if (!cur.mark())
                        cur.clearSelection();
-               cursorTop();
+               cursorTop(cur);
                finishChange(cur);
                break;
 
        case LFUN_ENDBUF:
                if (!cur.mark())
                        cur.clearSelection();
-               cursorBottom();
+               cursorBottom(cur);
                finishChange(cur);
                break;
 
@@ -467,9 +465,9 @@ DispatchResult LyXText::dispatch(LCursor
                if (!cur.selection())
                        cur.resetAnchor();
                if (rtl())
-                       cursorLeft(true);
+                       cursorLeft(cur, true);
                else
-                       cursorRight(true);
+                       cursorRight(cur, true);
                finishChange(cur, true);
                break;
 
@@ -477,65 +475,65 @@ DispatchResult LyXText::dispatch(LCursor
                if (!cur.selection())
                        cur.resetAnchor();
                if (rtl())
-                       cursorRight(true);
+                       cursorRight(cur, true);
                else
-                       cursorLeft(true);
+                       cursorLeft(cur, true);
                finishChange(cur, true);
                break;
 
        case LFUN_UPSEL:
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorUp(true);
+               cursorUp(cur, true);
                finishChange(cur, true);
                break;
 
        case LFUN_DOWNSEL:
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorDown(true);
+               cursorDown(cur, true);
                finishChange(cur, true);
                break;
 
        case LFUN_UP_PARAGRAPHSEL:
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorUpParagraph();
+               cursorUpParagraph(cur);
                finishChange(cur, true);
                break;
 
        case LFUN_DOWN_PARAGRAPHSEL:
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorDownParagraph();
+               cursorDownParagraph(cur);
                finishChange(cur, true);
                break;
 
        case LFUN_PRIORSEL:
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorPrevious();
+               cursorPrevious(cur);
                finishChange(cur, true);
                break;
 
        case LFUN_NEXTSEL:
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorNext();
+               cursorNext(cur);
                finishChange(cur, true);
                break;
 
        case LFUN_HOMESEL:
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorHome();
+               cursorHome(cur);
                finishChange(cur, true);
                break;
 
        case LFUN_ENDSEL:
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorEnd();
+               cursorEnd(cur);
                finishChange(cur, true);
                break;
 
@@ -543,9 +541,9 @@ DispatchResult LyXText::dispatch(LCursor
                if (!cur.selection())
                        cur.resetAnchor();
                if (rtl())
-                       cursorLeftOneWord();
+                       cursorLeftOneWord(cur);
                else
-                       cursorRightOneWord();
+                       cursorRightOneWord(cur);
                finishChange(cur, true);
                break;
 
@@ -553,9 +551,9 @@ DispatchResult LyXText::dispatch(LCursor
                if (!cur.selection())
                        cur.resetAnchor();
                if (rtl())
-                       cursorRightOneWord();
+                       cursorRightOneWord(cur);
                else
-                       cursorLeftOneWord();
+                       cursorLeftOneWord(cur);
                finishChange(cur, true);
                break;
 
@@ -567,31 +565,31 @@ DispatchResult LyXText::dispatch(LCursor
 
        case LFUN_RIGHT:
                finishChange(cur);
-               return moveRight();
+               return moveRight(cur);
 
        case LFUN_LEFT:
                finishChange(cur);
-               return moveLeft();
+               return moveLeft(cur);
 
        case LFUN_UP:
                finishChange(cur);
-               return moveUp();
+               return moveUp(cur);
 
        case LFUN_DOWN:
                finishChange(cur);
-               return moveDown();
+               return moveDown(cur);
 
        case LFUN_UP_PARAGRAPH:
                if (!cur.mark())
                        cur.clearSelection();
-               cursorUpParagraph();
+               cursorUpParagraph(cur);
                finishChange(cur);
                break;
 
        case LFUN_DOWN_PARAGRAPH:
                if (!cur.mark())
                        cur.clearSelection();
-               cursorDownParagraph();
+               cursorDownParagraph(cur);
                finishChange(cur, false);
                break;
 
@@ -599,31 +597,32 @@ DispatchResult LyXText::dispatch(LCursor
                if (!cur.mark())
                        cur.clearSelection();
                finishChange(cur, false);
-               if (cur.par() == 0 && cursorRow() == firstRow())
+               if (cur.par() == 0 && cur.textRow().pos() == 0)
                        return DispatchResult(false, FINISHED_UP);
-               cursorPrevious();
+               cursorPrevious(cur);
                break;
 
        case LFUN_NEXT:
                if (!cur.mark())
                        cur.clearSelection();
                finishChange(cur, false);
-               if (cur.par() == cur.lastpar() && cursorRow() == lastRow())
+               if (cur.par() == cur.lastpar()
+                         && cur.textRow().endpos() == cur.lastpos())
                        return DispatchResult(false, FINISHED_DOWN);
-               cursorNext();
+               cursorNext(cur);
                break;
 
        case LFUN_HOME:
                if (!cur.mark())
                        cur.clearSelection();
-               cursorHome();
+               cursorHome(cur);
                finishChange(cur, false);
                break;
 
        case LFUN_END:
                if (!cur.mark())
                        cur.clearSelection();
-               cursorEnd();
+               cursorEnd(cur);
                finishChange(cur, false);
                break;
 
@@ -639,7 +638,7 @@ DispatchResult LyXText::dispatch(LCursor
 
        case LFUN_DELETE:
                if (!cur.selection()) {
-                       Delete();
+                       Delete(cur);
                        cur.resetAnchor();
                        // It is possible to make it a lot faster still
                        // just comment out the line below...
@@ -653,15 +652,12 @@ DispatchResult LyXText::dispatch(LCursor
        case LFUN_DELETE_SKIP:
                // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
                if (!cur.selection()) {
-                       if (cursor().pos() == cursorPar()->size()) {
-                               cursorRight(bv);
-                               cursorLeft(bv);
-                               Delete();
-                               cur.resetAnchor();
-                       } else {
-                               Delete();
-                               cur.resetAnchor();
+                       if (cur.pos() == cur.lastpos()) {
+                               cursorRight(cur, true);
+                               cursorLeft(cur, true);
                        }
+                       Delete(cur);
+                       cur.resetAnchor();
                } else {
                        cutSelection(true, false);
                }
@@ -672,7 +668,7 @@ DispatchResult LyXText::dispatch(LCursor
        case LFUN_BACKSPACE:
                if (!cur.selection()) {
                        if (bv->owner()->getIntl().getTransManager().backspace()) {
-                               backspace();
+                               backspace(cur);
                                cur.resetAnchor();
                                // It is possible to make it a lot faster still
                                // just comment out the line below...
@@ -690,7 +686,7 @@ DispatchResult LyXText::dispatch(LCursor
                if (!cur.selection()) {
 #warning look here
                        //CursorSlice cur = cursor();
-                       backspace();
+                       backspace(cur);
                        //anchor() = cur;
                } else {
                        cutSelection(true, false);
@@ -700,7 +696,7 @@ DispatchResult LyXText::dispatch(LCursor
 
        case LFUN_BREAKPARAGRAPH:
                replaceSelection(this);
-               breakParagraph(bv->buffer()->paragraphs(), 0);
+               breakParagraph(cur, 0);
                bv->update();
                cur.resetAnchor();
                bv->switchKeyMap();
@@ -709,7 +705,7 @@ DispatchResult LyXText::dispatch(LCursor
 
        case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
                replaceSelection(this);
-               breakParagraph(bv->buffer()->paragraphs(), 1);
+               breakParagraph(cur, 1);
                bv->update();
                cur.resetAnchor();
                bv->switchKeyMap();
@@ -721,16 +717,15 @@ DispatchResult LyXText::dispatch(LCursor
                // indentation and add a "defskip" at the top.
                // Otherwise, do the same as LFUN_BREAKPARAGRAPH.
 #warning look here
-//             CursorSlice cur = cursor();
                replaceSelection(this);
                if (cur.pos() == 0) {
-                       ParagraphParameters & params = getPar(cur.current())->params();
+                       ParagraphParameters & params = cur.paragraph().params();
                        setParagraph(
                                        params.spacing(),
                                        params.align(),
                                        params.labelWidthString(), 1);
                } else {
-                       breakParagraph(bv->buffer()->paragraphs(), 0);
+                       breakParagraph(cur, 0);
                }
                bv->update();
 //     anchor() = cur;
@@ -740,11 +735,11 @@ DispatchResult LyXText::dispatch(LCursor
        }
 
        case LFUN_PARAGRAPH_SPACING: {
-               ParagraphList::iterator pit = cursorPar();
-               Spacing::Space cur_spacing = pit->params().spacing().getSpace();
+               Paragraph & par = cur.paragraph();
+               Spacing::Space cur_spacing = par.params().spacing().getSpace();
                float cur_value = 1.0;
                if (cur_spacing == Spacing::Other)
-                       cur_value = pit->params().spacing().getValue();
+                       cur_value = par.params().spacing().getValue();
 
                istringstream is(cmd.argument);
                string tmp;
@@ -774,7 +769,7 @@ DispatchResult LyXText::dispatch(LCursor
                               << cmd.argument << endl;
                }
                if (cur_spacing != new_spacing || cur_value != new_value) {
-                       pit->params().spacing(Spacing(new_spacing, new_value));
+                       par.params().spacing(Spacing(new_spacing, new_value));
                        redoParagraph();
                        bv->update();
                }
@@ -890,7 +885,7 @@ DispatchResult LyXText::dispatch(LCursor
                        return DispatchResult(false);
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorTop();
+               cursorTop(cur);
                finishChange(cur, true);
                break;
 
@@ -899,7 +894,7 @@ DispatchResult LyXText::dispatch(LCursor
                        return DispatchResult(false);
                if (!cur.selection())
                        cur.resetAnchor();
-               cursorBottom();
+               cursorBottom(cur);
                finishChange(cur, true);
                break;
 
@@ -1070,9 +1065,9 @@ DispatchResult LyXText::dispatch(LCursor
        case LFUN_MOUSE_TRIPLE:
                if (cmd.button() == mouse_button::button1) {
                        selection_possible = true;
-                       cursorHome();
+                       cursorHome(cur);
                        cur.resetAnchor();
-                       cursorEnd();
+                       cursorEnd(cur);
                        cur.setSelection();
                        bv->haveSelection(cur.selection());
                }
@@ -1107,9 +1102,9 @@ DispatchResult LyXText::dispatch(LCursor
                // FIXME: shouldn't be top-text-specific
                if (cursorrow == cursorRow() && !in_inset_) {
                        if (cmd.y - bv->top_y() >= bv->workHeight())
-                               cursorDown(true);
+                               cursorDown(cur, true);
                        else if (cmd.y - bv->top_y() < 0)
-                               cursorUp(true);
+                               cursorUp(cur, true);
                }
 
                // don't set anchor_
@@ -1450,31 +1445,31 @@ DispatchResult LyXText::dispatch(LCursor
        case LFUN_FINISHED_LEFT:
                lyxerr << "handle LFUN_FINISHED_LEFT" << endl;
                cur.pop(cur.currentDepth());
-               cur.bv().cursor() = cur;
                if (rtl())
-                       cursorLeft(true);
+                       cursorLeft(cur, true);
+               cur.bv().cursor() = cur;
                break;
 
        case LFUN_FINISHED_RIGHT:
                lyxerr << "handle LFUN_FINISHED_RIGHT" << endl;
                cur.pop(cur.currentDepth());
-               cur.bv().cursor() = cur;
                if (!rtl())
-                       cursorRight(true);
+                       cursorRight(cur, true);
+               cur.bv().cursor() = cur;
                break;
 
        case LFUN_FINISHED_UP:
                lyxerr << "handle LFUN_FINISHED_UP" << endl;
                cur.pop(cur.currentDepth());
+               cursorUp(cur, true);
                cur.bv().cursor() = cur;
-               cursorUp(true);
                break;
 
        case LFUN_FINISHED_DOWN:
                lyxerr << "handle LFUN_FINISHED_DOWN" << endl;
                cur.pop(cur.currentDepth());
+               cursorDown(cur, true);
                cur.bv().cursor() = cur;
-               cursorDown(true);
                break;
 
        case LFUN_LAYOUT_PARAGRAPH: {
Index: BufferView.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.C,v
retrieving revision 1.230
diff -u -p -r1.230 BufferView.C
--- BufferView.C        11 Feb 2004 14:45:37 -0000      1.230
+++ BufferView.C        12 Feb 2004 14:56:43 -0000
@@ -264,7 +264,7 @@ bool BufferView::insertLyXFile(string co
        string const fname = MakeAbsPath(filen);
 
        cursor().clearSelection();
-       text()->breakParagraph(buffer()->paragraphs());
+       text()->breakParagraph(cursor());
 
        bool res = buffer()->readFile(fname, text()->cursorPar());
        resize();
@@ -299,7 +299,9 @@ void BufferView::setCursorFromRow(int ro
        if (tmpid == -1)
                text()->setCursor(0, 0);
        else
-               text()->setCursor(buffer()->getParFromID(tmpid).pit(), tmppos);
+               text()->setCursor(
+                       text()->parOffset(buffer()->getParFromID(tmpid).pit()),
+                       tmppos);
 }
 
 
@@ -334,7 +336,7 @@ void BufferView::replaceWord(string cons
 
        // Go back so that replacement string is also spellchecked
        for (string::size_type i = 0; i < replacestring.length() + 1; ++i)
-               t->cursorLeft(this);
+               t->cursorLeft(cursor(), this);
 
        // FIXME: should be done through LFUN
        buffer()->markDirty();
@@ -417,7 +419,7 @@ void BufferView::setCursor(ParIterator c
                (*positions[i].it)->inset->edit(cur, true);
        cur.resetAnchor();
        LyXText * lt = par.text(*buffer());
-       lt->setCursor(par.pit(), pos);
+       lt->setCursor(lt->parOffset(par.pit()), pos);
 }
 
 
@@ -449,7 +451,7 @@ void BufferView::putSelectionAt(PosItera
        if (par.inset())
                top_y(par.outerPar()->y);
        update();
-       text->setCursor(cur.pit(), cur.pos());
+       text->setCursor(text->parOffset(cur.pit()), cur.pos());
        cursor().updatePos();
 
        if (length) {
Index: BufferView_pimpl.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v
retrieving revision 1.506
diff -u -p -r1.506 BufferView_pimpl.C
--- BufferView_pimpl.C  11 Feb 2004 14:45:38 -0000      1.506
+++ BufferView_pimpl.C  12 Feb 2004 14:56:43 -0000
@@ -684,7 +684,7 @@ void BufferView::Pimpl::restorePosition(
        if (par == buffer_->par_iterator_end())
                return;
 
-       bv_->text()->setCursor(par.pit(),
+       bv_->text()->setCursor(bv_->text()->parOffset(par.pit()),
                             min(par->size(), saved_positions[i].par_pos));
 
        if (i > 0)
@@ -1064,19 +1064,24 @@ bool BufferView::Pimpl::dispatch(FuncReq
        break;
 
        case LFUN_FLOAT_LIST:
+#warning Look here!
+               // Note that this seems to access the main lyx text only whereas the
+               // cursor stuff goes some possibly nested text. Would be good to
+               // make sure we are on the outermost level.
+
                if (tclass.floats().typeExist(cmd.argument)) {
                        InsetBase * inset = new InsetFloatList(cmd.argument);
                
                        // not quite sure if we want this...
-                       bv_->text()->recUndo(bv_->text()->cursor().par());
+                       bv_->text()->recUndo(bv_->cursor().par());
                        freezeUndo();
 
                        cur.clearSelection();
-                       bv_->text()->breakParagraph(bv_->buffer()->paragraphs());
+                       bv_->text()->breakParagraph(bv_->cursor());
 
                        if (!bv_->text()->cursorPar()->empty()) {
-                               bv_->text()->cursorLeft(true);
-                               
bv_->text()->breakParagraph(bv_->buffer()->paragraphs());
+                               bv_->text()->cursorLeft(bv_->cursor(), true);
+                               bv_->text()->breakParagraph(bv_->cursor());
                        }
 
                        bv_->text()->setLayout(tclass.defaultLayoutName());
Index: cursor.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.C,v
retrieving revision 1.54
diff -u -p -r1.54 cursor.C
--- cursor.C    11 Feb 2004 14:45:39 -0000      1.54
+++ cursor.C    12 Feb 2004 14:56:43 -0000
@@ -482,6 +482,18 @@ Paragraph const & LCursor::paragraph() c
 }
 
 
+Row & LCursor::textRow()
+{
+       return *paragraph().getRow(pos());
+}
+
+
+Row const & LCursor::textRow() const
+{
+       return *paragraph().getRow(pos());
+}
+
+
 LCursor::par_type LCursor::lastpar() const
 {
        return inMathed() ? 0 : text()->paragraphs().size() - 1;
Index: cursor.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.h,v
retrieving revision 1.32
diff -u -p -r1.32 cursor.h
--- cursor.h    11 Feb 2004 14:45:39 -0000      1.32
+++ cursor.h    12 Feb 2004 14:56:44 -0000
@@ -25,22 +25,20 @@ class FuncRequest;
 class InsetTabular;
 class LyXText;
 class Paragraph;
+class Row;
 
 
 // these should go
 class MathHullInset;
-class PainterInfo;
 class MathUnknownInset;
 class MathGridInset;
 
 
 // only needed for gcc 2.95, remove when support terminated
-
-
 template <typename A, typename B>
 bool ptr_cmp(A const * a, B const * b)
 {
-return a == b;
+       return a == b;
 }
 
 
@@ -218,14 +216,18 @@ public:
 
        //
        // text-specific part
-       ///
+       /// see comment for boundary_ below
        bool boundary() const { return current().boundary(); }
-       ///
+       /// see comment for boundary_ below
        bool & boundary() { return current().boundary(); }
-       ///
+       /// the paragraph we're in
        Paragraph & paragraph();
-       ///
+       /// the paragraph we're in
        Paragraph const & paragraph() const;
+       /// the row in the paragraph we're in
+       Row & textRow();
+       /// the row in the paragraph we're in
+       Row const & textRow() const;
        ///
        LyXText * text() const;
        ///

Reply via email to