]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView_pimpl.C
more cursor dispatch
[lyx.git] / src / BufferView_pimpl.C
index 9277ed07fbba3cc446ccbbbb9cdc35823c2263cd..2f136433d3c45c035a611ced279ec5f0b86b216f 100644 (file)
@@ -4,7 +4,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Asger Alstrup
- * \author Alfredo Braustein
+ * \author Alfredo Braunstein
  * \author Lars Gullik Bjønnes
  * \author Jean-Marc Lasgouttes
  * \author Angus Leeming
@@ -59,8 +59,6 @@
 
 #include "graphics/Previews.h"
 
-#include "mathed/formulabase.h"
-
 #include "support/filetools.h"
 #include "support/globbing.h"
 #include "support/path_defines.h"
@@ -111,9 +109,9 @@ boost::signals::connection lostcon;
 } // anon namespace
 
 
-BufferView::Pimpl::Pimpl(BufferView * bv, LyXView * owner,
+BufferView::Pimpl::Pimpl(BufferView & bv, LyXView * owner,
             int xpos, int ypos, int width, int height)
-       : bv_(bv), owner_(owner), buffer_(0), cursor_timeout(400),
+       : bv_(&bv), owner_(owner), buffer_(0), cursor_timeout(400),
          using_xterm_cursor(false), cursor_(bv)
 {
        xsel_cache_.set = false;
@@ -160,13 +158,20 @@ void BufferView::Pimpl::connectBuffer(Buffer & buf)
        if (errorConnection_.connected())
                disconnectBuffer();
 
-       errorConnection_ = buf.error.connect(boost::bind(&BufferView::Pimpl::addError, this, _1));
-       messageConnection_ = buf.message.connect(boost::bind(&LyXView::message, owner_, _1));
-       busyConnection_ = buf.busy.connect(boost::bind(&LyXView::busy, owner_, _1));
-       titleConnection_ = buf.updateTitles.connect(boost::bind(&LyXView::updateWindowTitle, owner_));
-       timerConnection_ = buf.resetAutosaveTimers.connect(boost::bind(&LyXView::resetAutosaveTimer, owner_));
-       readonlyConnection_ = buf.readonly.connect(boost::bind(&BufferView::Pimpl::showReadonly, this, _1));
-       closingConnection_ = buf.closing.connect(boost::bind(&BufferView::Pimpl::buffer, this, (Buffer *)0));
+       errorConnection_ =
+               buf.error.connect(boost::bind(&BufferView::Pimpl::addError, this, _1));
+       messageConnection_ =
+               buf.message.connect(boost::bind(&LyXView::message, owner_, _1));
+       busyConnection_ =
+               buf.busy.connect(boost::bind(&LyXView::busy, owner_, _1));
+       titleConnection_ =
+               buf.updateTitles.connect(boost::bind(&LyXView::updateWindowTitle, owner_));
+       timerConnection_ =
+               buf.resetAutosaveTimers.connect(boost::bind(&LyXView::resetAutosaveTimer, owner_));
+       readonlyConnection_ =
+               buf.readonly.connect(boost::bind(&BufferView::Pimpl::showReadonly, this, _1));
+       closingConnection_ =
+               buf.closing.connect(boost::bind(&BufferView::Pimpl::buffer, this, (Buffer *)0));
 }
 
 
@@ -295,6 +300,9 @@ void BufferView::Pimpl::buffer(Buffer * b)
                //bv_->setText(0);
        }
 
+       // reset old cursor
+       cursor_.reset();
+
        // set current buffer
        buffer_ = b;
 
@@ -320,9 +328,6 @@ void BufferView::Pimpl::buffer(Buffer * b)
                if (bv_->text() == 0)
                        resizeCurrentBuffer();
 
-               // FIXME: needed when ?
-               fitCursor();
-
                // Buffer-dependent dialogs should be updated or
                // hidden. This should go here because some dialogs (eg ToC)
                // require bv_->text.
@@ -350,7 +355,6 @@ void BufferView::Pimpl::buffer(Buffer * b)
 
 bool BufferView::Pimpl::fitCursor()
 {
-       lyxerr << "BufferView::Pimpl::fitCursor." << endl;
        if (screen().fitCursor(bv_)) {
                updateScrollbar();
                return true;
@@ -381,7 +385,7 @@ void BufferView::Pimpl::resizeCurrentBuffer()
        pos_type pos = 0;
        pos_type selstartpos = 0;
        pos_type selendpos = 0;
-       bool selection = false;
+       bool sel = false;
        bool mark_set  = false;
 
        owner_->busy(true);
@@ -393,33 +397,34 @@ void BufferView::Pimpl::resizeCurrentBuffer()
        if (!text)
                return;
 
-       par = text->cursor().par();
-       pos = text->cursor().pos();
-       selstartpar = text->selStart().par();
-       selstartpos = text->selStart().pos();
-       selendpar = text->selEnd().par();
-       selendpos = text->selEnd().pos();
-       selection = text->selection.set();
-       mark_set = text->selection.mark();
+       LCursor & cur = bv_->cursor();
+       par = cur.par();
+       pos = cur.pos();
+       selstartpar = cur.selBegin().par();
+       selstartpos = cur.selBegin().pos();
+       selendpar = cur.selEnd().par();
+       selendpos = cur.selEnd().pos();
+       sel = cur.selection();
+       mark_set = cur.mark();
        text->textwidth_ = bv_->workWidth();
        text->fullRebreak();
        update();
 
        if (par != -1) {
-               text->selection.set(true);
+               cur.selection() = true;
                // At this point just to avoid the Delete-Empty-Paragraph-
                // Mechanism when setting the cursor.
-               text->selection.mark(mark_set);
-               if (selection) {
+               cur.mark() = mark_set;
+               if (sel) {
                        text->setCursor(selstartpar, selstartpos);
-                       text->anchor() = text->cursor();
+                       cur.resetAnchor();
                        text->setCursor(selendpar, selendpos);
-                       text->setSelection();
+                       cur.setSelection();
                        text->setCursor(par, pos);
                } else {
                        text->setCursor(par, pos);
-                       text->anchor() = text->cursor();
-                       text->selection.set(false);
+                       cur.resetAnchor();
+                       cur.selection() = false;
                }
        }
 
@@ -472,9 +477,10 @@ void BufferView::Pimpl::scrollDocView(int value)
        int const last = top_y() + workarea().workHeight() - height;
 
        LyXText * text = bv_->text();
-       if (text->cursorY() < first)
+       int y = text->cursorY(bv_->cursor().cursor_.front());
+       if (y < first)
                text->setCursorFromCoordinates(0, first);
-       else if (text->cursorY() > last)
+       else if (y > last)
                text->setCursorFromCoordinates(0, last);
 
        owner_->updateLayoutChoice();
@@ -529,21 +535,21 @@ void BufferView::Pimpl::selectionRequested()
        if (!available())
                return;
 
-       LyXText * text = bv_->getLyXText();
+       LCursor & cur = bv_->cursor();
 
-       if (!text->selection.set()) {
+       if (!cur.selection()) {
                xsel_cache_.set = false;
                return;
        }
 
        if (!xsel_cache_.set ||
-           text->cursor() != xsel_cache_.cursor ||
-           text->anchor() != xsel_cache_.anchor)
+           cur.cursor_.back() != xsel_cache_.cursor ||
+           cur.anchor_.back() != xsel_cache_.anchor)
        {
-               xsel_cache_.cursor = text->cursor();
-               xsel_cache_.anchor = text->anchor();
-               xsel_cache_.set = text->selection.set();
-               sel = text->selectionAsString(*bv_->buffer(), false);
+               xsel_cache_.cursor = cur.cursor_.back();
+               xsel_cache_.anchor = cur.anchor_.back();
+               xsel_cache_.set = cur.selection();
+               sel = bv_->getLyXText()->selectionAsString(*bv_->buffer(), false);
                if (!sel.empty())
                        workarea().putClipboard(sel);
        } 
@@ -554,7 +560,7 @@ void BufferView::Pimpl::selectionLost()
 {
        if (available()) {
                screen().hideCursor();
-               bv_->getLyXText()->clearSelection();
+               bv_->cursor().clearSelection();
                xsel_cache_.set = false;
        }
 }
@@ -633,12 +639,13 @@ Change const BufferView::Pimpl::getCurrentChange()
                return Change(Change::UNCHANGED);
 
        LyXText * text = bv_->getLyXText();
+       LCursor & cur = bv_->cursor();
 
-       if (!text->selection.set())
+       if (!cur.selection())
                return Change(Change::UNCHANGED);
 
-       return text->getPar(text->selStart())
-               ->lookupChangeFull(text->selStart().pos());
+       return text->getPar(cur.selBegin())
+               ->lookupChangeFull(cur.selBegin().pos());
 }
 
 
@@ -661,7 +668,7 @@ void BufferView::Pimpl::restorePosition(unsigned int i)
 
        string const fname = saved_positions[i].filename;
 
-       bv_->text()->clearSelection();
+       bv_->cursor().clearSelection();
 
        if (fname != buffer_->fileName()) {
                Buffer * b = 0;
@@ -713,9 +720,11 @@ void BufferView::Pimpl::center()
 {
        LyXText * text = bv_->text();
 
-       text->clearSelection();
+       bv_->cursor().clearSelection();
        int const half_height = workarea().workHeight() / 2;
-       int new_y = std::max(0, text->cursorY() - half_height);
+       int new_y = text->cursorY(bv_->cursor().cursor_.front()) - half_height;
+       if (new_y < 0)
+               new_y = 0;
 
        // FIXME: look at this comment again ...
        // This updates top_y() but means the fitCursor() call
@@ -725,7 +734,7 @@ void BufferView::Pimpl::center()
        // to do it manually. Any operation that does a center()
        // and also might have moved top_y() must make sure to call
        // updateScrollbar() currently. Never mind that this is a
-       // pretty obfuscated way of updating t->top_y()
+       // pretty obfuscated way of updating text->top_y()
        top_y(new_y);
 }
 
@@ -736,10 +745,10 @@ void BufferView::Pimpl::stuffClipboard(string const & stuff) const
 }
 
 
-InsetOld * BufferView::Pimpl::getInsetByCode(InsetOld::Code code)
+InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code code)
 {
 #if 0
-       LyXCursor cursor = bv_->getLyXText()->cursor;
+       CursorSlice cursor = bv_->getLyXText()->cursor;
        Buffer::inset_iterator it =
                find_if(Buffer::inset_iterator(
                        cursorPar(), cursor().pos()),
@@ -751,7 +760,7 @@ InsetOld * BufferView::Pimpl::getInsetByCode(InsetOld::Code code)
        // should work for now. Better infrastructure is coming. (Lgb)
 
        Buffer * b = bv_->buffer();
-       LyXText * text =  bv_->getLyXText();
+       LyXText * text = bv_->getLyXText();
 
        Buffer::inset_iterator beg = b->inset_iterator_begin();
        Buffer::inset_iterator end = b->inset_iterator_end();
@@ -766,7 +775,8 @@ InsetOld * BufferView::Pimpl::getInsetByCode(InsetOld::Code code)
                        if (beg.getPar() == text->cursorPar()
                            && beg.getPos() >= text->cursor().pos()) {
                                break;
-                       } else if (beg.getPar() != text->cursorPar()) {
+                       }
+                       if (beg.getPar() != text->cursorPar()) {
                                break;
                        }
                }
@@ -775,9 +785,8 @@ InsetOld * BufferView::Pimpl::getInsetByCode(InsetOld::Code code)
        if (beg != end) {
                // Now find the first inset that matches code.
                for (; beg != end; ++beg) {
-                       if (beg->lyxCode() == code) {
+                       if (beg->lyxCode() == code)
                                return &(*beg);
-                       }
                }
        }
        return 0;
@@ -785,9 +794,9 @@ InsetOld * BufferView::Pimpl::getInsetByCode(InsetOld::Code code)
 }
 
 
-void BufferView::Pimpl::MenuInsertLyXFile(string const & filen)
+void BufferView::Pimpl::MenuInsertLyXFile(string const & filenm)
 {
-       string filename = filen;
+       string filename = filenm;
 
        if (filename.empty()) {
                // Launch a file browser
@@ -841,7 +850,7 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen)
 
 void BufferView::Pimpl::trackChanges()
 {
-       Buffer * buf(bv_->buffer());
+       Buffer * buf = bv_->buffer();
        bool const tracking(buf->params().tracking_changes);
 
        if (!tracking) {
@@ -871,69 +880,39 @@ void BufferView::Pimpl::trackChanges()
        buf->redostack().clear();
 }
 
-#warning remove me
-LCursor theTempCursor(0);
-
-namespace {
-
-       InsetOld * insetFromCoords(BufferView * bv, int x, int y)
-       {
-               lyxerr << "insetFromCoords" << endl;
-               LyXText * text = bv->text();
-               InsetOld * inset = 0;
-               theTempCursor = LCursor(bv);
-               while (true) {
-                       InsetOld * const inset_hit = text->checkInsetHit(x, y);
-                       if (!inset_hit) {
-                               lyxerr << "no further inset hit" << endl;
-                               break;
-                       }
-                       inset = inset_hit;
-                       if (!inset->descendable()) {
-                               lyxerr << "not descendable" << endl;
-                               break;
-                       }
-                       int const cell = inset->getCell(x, y + bv->top_y());
-                       if (cell == -1)
-                               break;
-                       text = inset_hit->getText(cell);
-                       lyxerr << "Hit inset: " << inset << " at x: " << x
-                               << " text: " << text << " y: " << y << endl;
-                       theTempCursor.push(static_cast<UpdatableInset*>(inset));
-               }
-               lyxerr << "theTempCursor: " << theTempCursor << endl;
-               return inset;
-       }
-
-}
-
 
-bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd)
+bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
 {
+       //
+       // this is only called for mouse related events.
+       //
+       FuncRequest cmd = cmd0;
+       cmd.y += bv_->top_y();
+       lyxerr << "*** workAreaDispatch: request: " << cmd << std::endl;
+       LCursor cur(*bv_);
        switch (cmd.action) {
+#if 0
        case LFUN_MOUSE_MOTION: {
                if (!available())
                        return false;
-               FuncRequest cmd1(cmd, bv_);
-               UpdatableInset * inset = bv_->cursor().innerInset();
+               FuncRequest cmd1 = cmd;
+               InsetBase * inset = cur.inset();
                DispatchResult res;
                if (inset) {
-                       cmd1.x -= inset->x();
-                       cmd1.y -= inset->y();
-                       res = inset->dispatch(cmd1);
+                       res = inset->dispatch(cur, cmd);
                } else {
-                       cmd1.y += bv_->top_y();
-                       res = bv_->cursor().innerText()->dispatch(cmd1);
+                       res = bv_->text()->dispatch(cur, cmd);
                }
 
-               if (bv_->fitCursor() || res.update()) {
+               if (fitCursor() || res.update()) {
                        bv_->update();
-                       bv_->cursor().updatePos();
+                       cur.updatePos();
                }
-
                return true;
        }
+#endif
 
+       case LFUN_MOUSE_MOTION:
        case LFUN_MOUSE_PRESS:
        case LFUN_MOUSE_RELEASE:
        case LFUN_MOUSE_DOUBLE:
@@ -950,58 +929,26 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd)
 
                screen().hideCursor();
 
-               // either the inset under the cursor or the surrounding LyXText will
-               // handle this event.
+               // either the inset under the cursor or the
+               // surrounding LyXText will handle this event.
 
                // built temporary path to inset
-               InsetOld * inset = insetFromCoords(bv_, cmd.x, cmd.y);
-               FuncRequest cmd1(cmd, bv_);
-               DispatchResult res;
+               LyXText * text = bv_->text();
+               InsetBase * const inset_hit = text->checkInsetHit(cmd.x, cmd.y);
+               if (inset_hit) 
+                       inset_hit->edit(cur, cmd.x, cmd.y);
+               else
+                       text->setCursorFromCoordinates(cur.current(), cmd.x, cmd.y);
+               lyxerr << "created temp cursor: " << cur << endl;
 
-               // try to dispatch to that inset
-               if (inset) {
-                       FuncRequest cmd2 = cmd1;
-                       lyxerr << "dispatching action " << cmd2.action
-                              << " to inset " << inset << endl;
-                       cmd2.x -= inset->x();
-                       cmd2.y -= inset->y();
-                       res = inset->dispatch(cmd2);
-                       if (res.update()) {
-                               bv_->update();
-                               bv_->cursor().updatePos();
-                       }
-                       res.update(false);
-                       switch (res.val()) {
-                               case FINISHED:
-                               case FINISHED_RIGHT:
-                               case FINISHED_UP:
-                               case FINISHED_DOWN:
-                                       theTempCursor.pop();
-                                       bv_->cursor() = theTempCursor;
-                                       bv_->cursor().innerText()->setCursorFromCoordinates(cmd.x, top_y() + cmd.y);
-                                       if (bv_->fitCursor())
-                                               bv_->update();
-                                       return true;
-                               default:
-                                       lyxerr << "not dispatched by inner inset val: " << res.val() << endl;
-                                       break;
-                       }
-               }
+               // Dispatch to the temp cursor.
+               // An inset (or LyXText) can assign this to bv->cursor()
+               // if it wishes to do so.
+               DispatchResult res = cur.dispatch(cmd);
+
+               if (fitCursor() || res.update())
+                       bv_->update();
 
-               // otherwise set cursor to surrounding LyXText
-               if (!res.dispatched()) {
-                       lyxerr << "temp cursor is: " << theTempCursor << endl;
-                       lyxerr << "dispatching " << cmd1
-                              << " to surrounding LyXText "
-                              << theTempCursor.innerText() << endl;
-                       bv_->cursor() = theTempCursor;
-                       cmd1.y += bv_->top_y();
-                       res = bv_->cursor().innerText()->dispatch(cmd1);
-                       if (bv_->fitCursor() || res.update())
-                               bv_->update();
-
-                       //return DispatchResult(true, true);
-               }
                // see workAreaKeyPress
                cursor_timeout.restart();
                screen().showCursor(*bv_);
@@ -1020,29 +967,29 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd)
        }
 
        default:
-               owner_->dispatch(cmd);
-               return true;
+               lyxerr << "*** UNDISPATCHED: " << cmd;
+               //owner_->dispatch(cmd);
        }
+       return true;
 }
 
 
-bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
+bool BufferView::Pimpl::dispatch(FuncRequest const & cmd)
 {
+       lyxerr << "*** BufferView::Pimpl: request: " << cmd << std::endl;
        // Make sure that the cached BufferView is correct.
-       FuncRequest ev = ev_in;
-       ev.setView(bv_);
-
        lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:"
-               << " action[" << ev.action << ']'
-               << " arg[" << ev.argument << ']'
-               << " x[" << ev.x << ']'
-               << " y[" << ev.y << ']'
-               << " button[" << ev.button() << ']'
+               << " action[" << cmd.action << ']'
+               << " arg[" << cmd.argument << ']'
+               << " x[" << cmd.x << ']'
+               << " y[" << cmd.y << ']'
+               << " button[" << cmd.button() << ']'
                << endl;
 
        LyXTextClass const & tclass = buffer_->params().getLyXTextClass();
+       LCursor & cur = bv_->cursor();
 
-       switch (ev.action) {
+       switch (cmd.action) {
 
        case LFUN_SCROLL_INSET:
                // this is not handled here as this function is only active
@@ -1051,15 +998,15 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
                break;
 
        case LFUN_FILE_INSERT:
-               MenuInsertLyXFile(ev.argument);
+               MenuInsertLyXFile(cmd.argument);
                break;
 
        case LFUN_FILE_INSERT_ASCII_PARA:
-               InsertAsciiFile(bv_, ev.argument, true);
+               InsertAsciiFile(bv_, cmd.argument, true);
                break;
 
        case LFUN_FILE_INSERT_ASCII:
-               InsertAsciiFile(bv_, ev.argument, false);
+               InsertAsciiFile(bv_, cmd.argument, false);
                break;
 
        case LFUN_FONT_STATE:
@@ -1068,8 +1015,8 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
 
        case LFUN_INSERT_LABEL: {
                // Try and generate a valid label
-               string const contents = ev.argument.empty() ?
-                       getPossibleLabel(*bv_) : ev.argument;
+               string const contents = cmd.argument.empty() ?
+                       getPossibleLabel(*bv_) : cmd.argument;
                InsetCommandParams icp("label", contents);
                string data = InsetCommandMailer::params2string("label", icp);
                owner_->getDialogs().show("label", data, 0);
@@ -1077,18 +1024,18 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
        }
 
        case LFUN_BOOKMARK_SAVE:
-               savePosition(strToUnsignedInt(ev.argument));
+               savePosition(strToUnsignedInt(cmd.argument));
                break;
 
        case LFUN_BOOKMARK_GOTO:
-               restorePosition(strToUnsignedInt(ev.argument));
+               restorePosition(strToUnsignedInt(cmd.argument));
                break;
 
        case LFUN_REF_GOTO: {
-               string label = ev.argument;
+               string label = cmd.argument;
                if (label.empty()) {
                        InsetRef * inset =
-                               static_cast<InsetRef*>(getInsetByCode(InsetOld::REF_CODE));
+                               static_cast<InsetRef*>(getInsetByCode(InsetBase::REF_CODE));
                        if (inset) {
                                label = inset->getContents();
                                savePosition(0);
@@ -1119,44 +1066,34 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
        case LFUN_HUNG_UMLAUT:
        case LFUN_CIRCLE:
        case LFUN_OGONEK:
-               if (ev.argument.empty()) {
+               if (cmd.argument.empty()) {
                        // As always...
-                       owner_->getLyXFunc().handleKeyFunc(ev.action);
+                       owner_->getLyXFunc().handleKeyFunc(cmd.action);
                } else {
-                       owner_->getLyXFunc().handleKeyFunc(ev.action);
+                       owner_->getLyXFunc().handleKeyFunc(cmd.action);
                        owner_->getIntl().getTransManager()
-                               .TranslateAndInsert(ev.argument[0], bv_->getLyXText());
+                               .TranslateAndInsert(cmd.argument[0], bv_->getLyXText());
                        update();
                }
                break;
 
-       case LFUN_MATH_MACRO:
-       case LFUN_MATH_DELIM:
-       case LFUN_INSERT_MATRIX:
-       case LFUN_INSERT_MATH:
-       case LFUN_MATH_IMPORT_SELECTION: // Imports LaTeX from the X selection
-       case LFUN_MATH_DISPLAY:          // Open or create a displayed math inset
-       case LFUN_MATH_MODE:             // Open or create an inlined math inset
-               mathDispatch(ev);
-               break;
-
        case LFUN_INSET_INSERT: {
                // Same as above.
                BOOST_ASSERT(false);
-               InsetOld * inset = createInset(ev);
+               InsetBase * inset = createInset(bv_, cmd);
                if (!inset || !insertInset(inset))
                        delete inset;
                break;
        }
 
        case LFUN_FLOAT_LIST:
-               if (tclass.floats().typeExist(ev.argument)) {
-                       InsetOld * inset = new InsetFloatList(ev.argument);
+               if (tclass.floats().typeExist(cmd.argument)) {
+                       InsetBase * inset = new InsetFloatList(cmd.argument);
                        if (!insertInset(inset, tclass.defaultLayoutName()))
                                delete inset;
                } else {
                        lyxerr << "Non-existent float type: "
-                              << ev.argument << endl;
+                              << cmd.argument << endl;
                }
                break;
 
@@ -1173,11 +1110,11 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
                break;
 
        case LFUN_PARAGRAPH_APPLY:
-               setParagraphParams(*bv_, ev.argument);
+               setParagraphParams(*bv_, cmd.argument);
                break;
 
        case LFUN_THESAURUS_ENTRY: {
-               string arg = ev.argument;
+               string arg = cmd.argument;
 
                if (arg.empty()) {
                        arg = bv_->getLyXText()->selectionAsString(*buffer_,
@@ -1235,32 +1172,59 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
        }
 
        case LFUN_WORD_FIND:
-               lyx::find::find(ev);
+               lyx::find::find(bv_, cmd);
                break;
 
        case LFUN_WORD_REPLACE:
-               lyx::find::replace(ev);
+               lyx::find::replace(bv_, cmd);
+               break;
+
+       case LFUN_MARK_OFF:
+               cur.clearSelection();
+               bv_->update();
+               cur.resetAnchor();
+               cur.message(N_("Mark off"));
+               break;
+
+       case LFUN_MARK_ON:
+               cur.clearSelection();
+               cur.mark() = true;
+               bv_->update();
+               cur.resetAnchor();
+               cur.message(N_("Mark on"));
+               break;
+
+       case LFUN_SETMARK:
+               cur.clearSelection();
+               if (cur.mark()) {
+                       cur.message(N_("Mark removed"));
+               } else {
+                       cur.mark() = true;
+                       cur.message(N_("Mark set"));
+               }
+               cur.resetAnchor();
+               bv_->update();
                break;
 
        case LFUN_UNKNOWN_ACTION:
-               ev.errorMessage(N_("Unknown function!"));
+               cur.errorMessage(N_("Unknown function!"));
                break;
 
        default:
-               return bv_->getLyXText()->dispatch(FuncRequest(ev, bv_)).dispatched();
-       } // end of switch
+               return false;
+       }
 
        return true;
 }
 
 
-bool BufferView::Pimpl::insertInset(InsetOld * inset, string const & lout)
+bool BufferView::Pimpl::insertInset(InsetBase * inset, string const & lout)
 {
        // not quite sure if we want this...
        bv_->text()->recUndo(bv_->text()->cursor().par());
        freezeUndo();
 
-       bv_->text()->clearSelection();
+       bv_->cursor().clearSelection();
        if (!lout.empty()) {
                bv_->text()->breakParagraph(bv_->buffer()->paragraphs());
 
@@ -1282,11 +1246,11 @@ bool BufferView::Pimpl::insertInset(InsetOld * inset, string const & lout)
 }
 
 
-bool BufferView::Pimpl::ChangeInsets(InsetOld::Code code,
+bool BufferView::Pimpl::ChangeInsets(InsetBase::Code code,
                                     string const & from, string const & to)
 {
        bool need_update = false;
-       LyXCursor cur = bv_->text()->cursor();
+       CursorSlice cur = bv_->text()->cursor();
 
        ParIterator end = bv_->buffer()->par_iterator_end();
        for (ParIterator it = bv_->buffer()->par_iterator_begin();
@@ -1324,12 +1288,14 @@ void BufferView::Pimpl::updateParagraphDialog()
 {
        if (!bv_->owner()->getDialogs().visible("paragraph"))
                return;
-       Paragraph const & par = *bv_->getLyXText()->cursorPar();
+       CursorSlice const & cur = bv_->cursor().innerTextSlice();
+       LyXText * text = bv_->cursor().innerText();
+       Paragraph const & par = *text->getPar(cur.par());
        string data;
        params2string(par, data);
 
        // Will the paragraph accept changes from the dialog?
-       InsetOld * const inset = par.inInset();
+       InsetBase * const inset = cur.inset();
        bool const accept =
                !(inset && inset->forceDefaultParagraphs(inset));