]> git.lyx.org Git - lyx.git/blobdiff - src/Text3.cpp
don't forget to pack numpunct_lyx_char_type.h
[lyx.git] / src / Text3.cpp
index 18adc7d4317dd5bb0791d8b6eb789d6796465b3e..0dd3b6492c96ee94fb1906e658d4fa0ae9533c95 100644 (file)
 #include "Language.h"
 #include "Layout.h"
 #include "LyXAction.h"
-#include "LyXFunc.h"
+#include "LyX.h"
 #include "Lexer.h"
 #include "LyXRC.h"
 #include "Paragraph.h"
 #include "ParagraphParameters.h"
+#include "SpellChecker.h"
 #include "TextClass.h"
 #include "TextMetrics.h"
 #include "VSpace.h"
+#include "WordLangTuple.h"
 
 #include "frontends/Application.h"
 #include "frontends/Clipboard.h"
@@ -196,9 +198,9 @@ static void mathDispatch(Cursor & cur, FuncRequest const & cmd, bool display)
 
 void regexpDispatch(Cursor & cur, FuncRequest const & cmd)
 {
-       BOOST_ASSERT(cmd.action == LFUN_REGEXP_MODE);
+       LASSERT(cmd.action() == LFUN_REGEXP_MODE, return);
        if (cur.inRegexped()) {
-               cur.message(_("Already in regexp mode"));
+               cur.message(_("Already in regular expression mode"));
                return;
        }
        cur.recordUndo();
@@ -237,7 +239,7 @@ static bool doInsertInset(Cursor & cur, Text * text,
                ci->setButtonLabel();
 
        cur.recordUndo();
-       if (cmd.action == LFUN_INDEX_INSERT) {
+       if (cmd.action() == LFUN_INDEX_INSERT) {
                docstring ds = subst(text->getStringToIndex(cur), '\n', ' ');
                text->insertInset(cur, inset);
                if (edit)
@@ -267,16 +269,19 @@ static bool doInsertInset(Cursor & cur, Text * text,
        cur.clearSelection(); // bug 393
        cur.finishUndo();
        InsetText * insetText = dynamic_cast<InsetText *>(inset);
-       if (insetText && (!insetText->allowMultiPar() || cur.lastpit() == 0)) {
-               // reset first par to default
-               cur.text()->paragraphs().begin()
-                       ->setPlainOrDefaultLayout(bparams.documentClass());
-               cur.pos() = 0;
-               cur.pit() = 0;
-               // Merge multiple paragraphs -- hack
-               while (cur.lastpit() > 0)
-                       mergeParagraph(bparams, cur.text()->paragraphs(), 0);
-               cur.leaveInset(*inset);
+       if (insetText) {
+               insetText->fixParagraphsFont();
+               if (!insetText->allowMultiPar() || cur.lastpit() == 0) {
+                       // reset first par to default
+                       cur.text()->paragraphs().begin()
+                               ->setPlainOrDefaultLayout(bparams.documentClass());
+                       cur.pos() = 0;
+                       cur.pit() = 0;
+                       // Merge multiple paragraphs -- hack
+                       while (cur.lastpit() > 0)
+                               mergeParagraph(bparams, cur.text()->paragraphs(), 0);
+                       cur.leaveInset(*inset);
+               }
        } else {
                cur.leaveInset(*inset);
                // reset surrounding par to default
@@ -286,7 +291,6 @@ static bool doInsertInset(Cursor & cur, Text * text,
                        : dc.defaultLayoutName();
                text->setLayout(cur, layoutname);
        }
-
        return true;
 }
 
@@ -297,59 +301,6 @@ string const freefont2string()
 }
 
 
-static void dragMove(Cursor & cur, int moveid, int movetoid)
-{
-       // Create pointers to buffers
-       Buffer & buf_move = *cur.buffer();
-       DocIterator dit_move = buf_move.getParFromID(moveid);
-       DocIterator dit_dest = buf_move.getParFromID(movetoid);
-
-       pit_type & pit_move = dit_move.pit();
-       pit_type & pit_dest = dit_dest.pit();
-       ParagraphList & pars = dit_move.text()->paragraphs();
-
-       // Create references to the paragraphs to be moved
-       ParagraphList::iterator const bgn = pars.begin();
-       ParagraphList::iterator dest_start = boost::next(bgn, pit_dest);
-
-       // The first paragraph of the area to be copied:
-       ParagraphList::iterator start = boost::next(bgn, pit_move);
-       // The final paragraph of area to be copied:
-       ParagraphList::iterator finish = start;
-       ParagraphList::iterator const end = pars.end();
-
-       // Move out (down) from this section header
-       if (finish != end)
-               ++finish;
-
-       // Seek the one (on same level) below
-       int const thistoclevel = start->layout().toclevel;
-       for (; finish != end; ++finish) {
-               int const toclevel = finish->layout().toclevel;
-               if (toclevel != Layout::NOT_IN_TOC
-                   && toclevel <= thistoclevel)
-                       break;
-       }
-
-       if (start == pars.begin() || start == dest_start)
-               // Nothing to move
-               return;
-
-       pars.insert(dest_start, start, finish);
-       pars.erase(start, finish);
-
-       // FIXME: This only really needs doing for the newly
-       // introduced paragraphs. Something like:
-       //      pit_type const numpars = distance(start, finish);
-       //      start = boost::next(bgn, pit);
-       //      finish = boost::next(start, numpars);
-       //      for (; start != finish; ++start)
-       //              start->setBuffer(buf);
-       // But while this seems to work, it is kind of fragile.
-       buf_move.inset().setBuffer(buf_move);
-}
-
-
 /// the type of outline operation
 enum OutlineOp {
        OutlineUp, // Move this header with text down
@@ -521,20 +472,21 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        bool sel = cur.selection();
        // Signals that, even if needsUpdate == false, an update of the
        // cursor paragraph is required
-       bool singleParUpdate = lyxaction.funcHasFlag(cmd.action,
+       bool singleParUpdate = lyxaction.funcHasFlag(cmd.action(),
                LyXAction::SingleParUpdate);
        // Signals that a full-screen update is required
-       bool needsUpdate = !(lyxaction.funcHasFlag(cmd.action,
+       bool needsUpdate = !(lyxaction.funcHasFlag(cmd.action(),
                LyXAction::NoUpdate) || singleParUpdate);
 
-       switch (cmd.action) {
+       FuncCode const act = cmd.action();
+       switch (act) {
 
        case LFUN_PARAGRAPH_MOVE_DOWN: {
                pit_type const pit = cur.pit();
                recUndo(cur, pit, pit + 1);
                cur.finishUndo();
                pars_.swap(pit, pit + 1);
-               cur.buffer()->updateLabels();
+               cur.buffer()->updateBuffer();
                needsUpdate = true;
                ++cur.pit();
                break;
@@ -545,7 +497,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                recUndo(cur, pit - 1, pit);
                cur.finishUndo();
                pars_.swap(pit, pit - 1);
-               cur.buffer()->updateLabels();
+               cur.buffer()->updateBuffer();
                --cur.pit();
                needsUpdate = true;
                break;
@@ -571,7 +523,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                par.params().startOfAppendix(start);
 
                // we can set the refreshing parameters now
-               cur.buffer()->updateLabels();
+               cur.buffer()->updateBuffer();
                break;
        }
 
@@ -601,7 +553,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_BUFFER_BEGIN:
        case LFUN_BUFFER_BEGIN_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_BEGIN_SELECT);
+               needsUpdate |= cur.selHandle(act == LFUN_BUFFER_BEGIN_SELECT);
                if (cur.depth() == 1)
                        needsUpdate |= cursorTop(cur);
                else
@@ -611,7 +563,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_BUFFER_END:
        case LFUN_BUFFER_END_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_END_SELECT);
+               needsUpdate |= cur.selHandle(act == LFUN_BUFFER_END_SELECT);
                if (cur.depth() == 1)
                        needsUpdate |= cursorBottom(cur);
                else
@@ -621,7 +573,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_INSET_BEGIN:
        case LFUN_INSET_BEGIN_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_INSET_BEGIN_SELECT);
+               needsUpdate |= cur.selHandle(act == LFUN_INSET_BEGIN_SELECT);
                if (cur.depth() == 1 || !cur.top().at_begin())
                        needsUpdate |= cursorTop(cur);
                else
@@ -631,7 +583,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_INSET_END:
        case LFUN_INSET_END_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_INSET_END_SELECT);
+               needsUpdate |= cur.selHandle(act == LFUN_INSET_END_SELECT);
                if (cur.depth() == 1 || !cur.top().at_end())
                        needsUpdate |= cursorBottom(cur);
                else
@@ -654,7 +606,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_CHAR_FORWARD:
        case LFUN_CHAR_FORWARD_SELECT:
                //LYXERR0(" LFUN_CHAR_FORWARD[SEL]:\n" << cur);
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT);
+               needsUpdate |= cur.selHandle(act == LFUN_CHAR_FORWARD_SELECT);
                needsUpdate |= cursorForward(cur);
 
                if (!needsUpdate && oldTopSlice == cur.top()
@@ -680,7 +632,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_CHAR_BACKWARD:
        case LFUN_CHAR_BACKWARD_SELECT:
                //lyxerr << "handle LFUN_CHAR_BACKWARD[_SELECT]:\n" << cur << endl;
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT);
+               needsUpdate |= cur.selHandle(act == LFUN_CHAR_BACKWARD_SELECT);
                needsUpdate |= cursorBackward(cur);
 
                if (!needsUpdate && oldTopSlice == cur.top()
@@ -706,7 +658,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_CHAR_LEFT:
        case LFUN_CHAR_LEFT_SELECT:
                if (lyxrc.visual_cursor) {
-                       needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_LEFT_SELECT);
+                       needsUpdate |= cur.selHandle(act == LFUN_CHAR_LEFT_SELECT);
                        needsUpdate |= cursorVisLeft(cur);
                        if (!needsUpdate && oldTopSlice == cur.top()
                                        && cur.boundary() == oldBoundary) {
@@ -715,11 +667,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        }
                } else {
                        if (reverseDirectionNeeded(cur)) {
-                               cmd.action = cmd.action == LFUN_CHAR_LEFT_SELECT ?
-                                       LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD;
+                               cmd.setAction(cmd.action() == LFUN_CHAR_LEFT_SELECT ?
+                                       LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD);
                        } else {
-                               cmd.action = cmd.action == LFUN_CHAR_LEFT_SELECT ?
-                                       LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD;
+                               cmd.setAction(cmd.action() == LFUN_CHAR_LEFT_SELECT ?
+                                       LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD);
                        }
                        dispatch(cur, cmd);
                        return;
@@ -729,7 +681,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_CHAR_RIGHT:
        case LFUN_CHAR_RIGHT_SELECT:
                if (lyxrc.visual_cursor) {
-                       needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_RIGHT_SELECT);
+                       needsUpdate |= cur.selHandle(cmd.action() == LFUN_CHAR_RIGHT_SELECT);
                        needsUpdate |= cursorVisRight(cur);
                        if (!needsUpdate && oldTopSlice == cur.top()
                                        && cur.boundary() == oldBoundary) {
@@ -738,11 +690,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        }
                } else {
                        if (reverseDirectionNeeded(cur)) {
-                               cmd.action = cmd.action == LFUN_CHAR_RIGHT_SELECT ?
-                                       LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD;
+                               cmd.setAction(cmd.action() == LFUN_CHAR_RIGHT_SELECT ?
+                                       LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD);
                        } else {
-                               cmd.action = cmd.action == LFUN_CHAR_RIGHT_SELECT ?
-                                       LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD;
+                               cmd.setAction(cmd.action() == LFUN_CHAR_RIGHT_SELECT ?
+                                       LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD);
                        }
                        dispatch(cur, cmd);
                        return;
@@ -755,11 +707,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_UP:
        case LFUN_DOWN: {
                // stop/start the selection
-               bool select = cmd.action == LFUN_DOWN_SELECT ||
-                       cmd.action == LFUN_UP_SELECT;
+               bool select = cmd.action() == LFUN_DOWN_SELECT ||
+                       cmd.action() == LFUN_UP_SELECT;
 
                // move cursor up/down
-               bool up = cmd.action == LFUN_UP_SELECT || cmd.action == LFUN_UP;
+               bool up = cmd.action() == LFUN_UP_SELECT || cmd.action() == LFUN_UP;
                bool const atFirstOrLastRow = cur.atFirstOrLastRow(up);
 
                if (!atFirstOrLastRow) {
@@ -781,25 +733,25 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_PARAGRAPH_UP:
        case LFUN_PARAGRAPH_UP_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT);
+               needsUpdate |= cur.selHandle(cmd.action() == LFUN_PARAGRAPH_UP_SELECT);
                needsUpdate |= cursorUpParagraph(cur);
                break;
 
        case LFUN_PARAGRAPH_DOWN:
        case LFUN_PARAGRAPH_DOWN_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT);
+               needsUpdate |= cur.selHandle(cmd.action() == LFUN_PARAGRAPH_DOWN_SELECT);
                needsUpdate |= cursorDownParagraph(cur);
                break;
 
        case LFUN_LINE_BEGIN:
        case LFUN_LINE_BEGIN_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT);
+               needsUpdate |= cur.selHandle(cmd.action() == LFUN_LINE_BEGIN_SELECT);
                needsUpdate |= tm->cursorHome(cur);
                break;
 
        case LFUN_LINE_END:
        case LFUN_LINE_END_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT);
+               needsUpdate |= cur.selHandle(cmd.action() == LFUN_LINE_END_SELECT);
                needsUpdate |= tm->cursorEnd(cur);
                break;
 
@@ -841,7 +793,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_WORD_RIGHT:
        case LFUN_WORD_RIGHT_SELECT:
                if (lyxrc.visual_cursor) {
-                       needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_RIGHT_SELECT);
+                       needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_RIGHT_SELECT);
                        needsUpdate |= cursorVisRightOneWord(cur);
                        if (!needsUpdate && oldTopSlice == cur.top()
                                        && cur.boundary() == oldBoundary) {
@@ -850,11 +802,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        }
                } else {
                        if (reverseDirectionNeeded(cur)) {
-                               cmd.action = cmd.action == LFUN_WORD_RIGHT_SELECT ?
-                                               LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD;
+                               cmd.setAction(cmd.action() == LFUN_WORD_RIGHT_SELECT ?
+                                               LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD);
                        } else {
-                               cmd.action = cmd.action == LFUN_WORD_RIGHT_SELECT ?
-                                               LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD;
+                               cmd.setAction(cmd.action() == LFUN_WORD_RIGHT_SELECT ?
+                                               LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD);
                        }
                        dispatch(cur, cmd);
                        return;
@@ -863,14 +815,14 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_WORD_FORWARD:
        case LFUN_WORD_FORWARD_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT);
+               needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_FORWARD_SELECT);
                needsUpdate |= cursorForwardOneWord(cur);
                break;
 
        case LFUN_WORD_LEFT:
        case LFUN_WORD_LEFT_SELECT:
                if (lyxrc.visual_cursor) {
-                       needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_LEFT_SELECT);
+                       needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_LEFT_SELECT);
                        needsUpdate |= cursorVisLeftOneWord(cur);
                        if (!needsUpdate && oldTopSlice == cur.top()
                                        && cur.boundary() == oldBoundary) {
@@ -879,11 +831,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        }
                } else {
                        if (reverseDirectionNeeded(cur)) {
-                               cmd.action = cmd.action == LFUN_WORD_LEFT_SELECT ?
-                                               LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD;
+                               cmd.setAction(cmd.action() == LFUN_WORD_LEFT_SELECT ?
+                                               LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD);
                        } else {
-                               cmd.action = cmd.action == LFUN_WORD_LEFT_SELECT ?
-                                               LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD;
+                               cmd.setAction(cmd.action() == LFUN_WORD_LEFT_SELECT ?
+                                               LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD);
                        }
                        dispatch(cur, cmd);
                        return;
@@ -892,7 +844,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_WORD_BACKWARD:
        case LFUN_WORD_BACKWARD_SELECT:
-               needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT);
+               needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_BACKWARD_SELECT);
                needsUpdate |= cursorBackwardOneWord(cur);
                break;
 
@@ -933,8 +885,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                                      bv->buffer().params().trackChanges);
                                // Update the selection pos to make sure the selection does not
                                // change as the inserted tab will increase the logical pos.
-                               if (cur.anchor_.pit() == pit)
-                                       cur.anchor_.forwardPos();
+                               if (cur.realAnchor().pit() == pit)
+                                       cur.realAnchor().forwardPos();
                                if (cur.pit() == pit)
                                        cur.forwardPos();
                        }
@@ -960,8 +912,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                if (par.getChar(0) == '\t') {
                                        if (cur.pit() == pit)
                                                cur.posBackward();
-                                       if (cur.anchor_.pit() == pit && cur.anchor_.pos() > 0 )
-                                               cur.anchor_.backwardPos();
+                                       if (cur.realAnchor().pit() == pit && cur.realAnchor().pos() > 0 )
+                                               cur.realAnchor().backwardPos();
                                        
                                        par.eraseChar(0, tc);
                                } else 
@@ -970,8 +922,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                             par.getChar(0) == ' ' && n_spaces < 4; ++n_spaces) {
                                                if (cur.pit() == pit)
                                                        cur.posBackward();
-                                               if (cur.anchor_.pit() == pit && cur.anchor_.pos() > 0 )
-                                                       cur.anchor_.backwardPos();
+                                               if (cur.realAnchor().pit() == pit && cur.realAnchor().pos() > 0 )
+                                                       cur.realAnchor().backwardPos();
                                                
                                                par.eraseChar(0, tc);
                                        }
@@ -1057,7 +1009,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                if (inset) {
                        // FIXME (Abdel 01/02/2006):
                        // What follows would be a partial fix for bug 2154:
-                       //   http://bugzilla.lyx.org/show_bug.cgi?id=2154
+                       //   http://www.lyx.org/trac/ticket/2154
                        // This automatically put the label inset _after_ a
                        // numbered section. It should be possible to extend the mechanism
                        // to any kind of LateX environement.
@@ -1403,14 +1355,17 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
 
        // Single-click on work area
-       case LFUN_MOUSE_PRESS:
+       case LFUN_MOUSE_PRESS: {
                // We are not marking a selection with the keyboard in any case.
-               cur.bv().cursor().setMark(false);
+               Cursor & bvcur = cur.bv().cursor();
+               bvcur.setMark(false);
                switch (cmd.button()) {
                case mouse_button::button1:
                        // Set the cursor
                        if (!bv->mouseSetCursor(cur, cmd.argument() == "region-select"))
                                cur.updateFlags(Update::SinglePar | Update::FitCursor);
+                       if (bvcur.wordSelection())
+                               selectWord(bvcur, WHOLE_WORD);
                        break;
 
                case mouse_button::button2:
@@ -1423,7 +1378,6 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        break;
 
                case mouse_button::button3: {
-                       Cursor const & bvcur = cur.bv().cursor();
                        // Don't do anything if we right-click a
                        // selection, a context menu will popup.
                        if (bvcur.selection() && cur >= bvcur.selectionBegin()
@@ -1440,7 +1394,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        break;
                } // switch (cmd.button())
                break;
-
+       }
        case LFUN_MOUSE_MOTION: {
                // Mouse motion with right or middle mouse do nothing for now.
                if (cmd.button() != mouse_button::button1) {
@@ -1449,26 +1403,26 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                }
                // ignore motions deeper nested than the real anchor
                Cursor & bvcur = cur.bv().cursor();
-               if (!bvcur.anchor_.hasPart(cur)) {
+               if (!bvcur.realAnchor().hasPart(cur)) {
                        cur.undispatched();
                        break;
                }
                CursorSlice old = bvcur.top();
 
                int const wh = bv->workHeight();
-               int const y = max(0, min(wh - 1, cmd.y));
+               int const y = max(0, min(wh - 1, cmd.y()));
 
-               tm->setCursorFromCoordinates(cur, cmd.x, y);
-               cur.setTargetX(cmd.x);
-               if (cmd.y >= wh)
+               tm->setCursorFromCoordinates(cur, cmd.x(), y);
+               cur.setTargetX(cmd.x());
+               if (cmd.y() >= wh)
                        lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT));
-               else if (cmd.y < 0)
+               else if (cmd.y() < 0)
                        lyx::dispatch(FuncRequest(LFUN_UP_SELECT));
                // This is to allow jumping over large insets
                if (cur.top() == old) {
-                       if (cmd.y >= wh)
+                       if (cmd.y() >= wh)
                                lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT));
-                       else if (cmd.y < 0)
+                       else if (cmd.y() < 0)
                                lyx::dispatch(FuncRequest(LFUN_UP_SELECT));
                }
                // We continue with our existing selection or start a new one, so don't
@@ -1618,13 +1572,14 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_MARGINALNOTE_INSERT:
        case LFUN_OPTIONAL_INSERT:
        case LFUN_INDEX_INSERT:
+       case LFUN_PREVIEW_INSERT:
                // Open the inset, and move the current selection
                // inside it.
                doInsertInset(cur, this, cmd, true, true);
                cur.posForward();
                // Some insets are numbered, others are shown in the outline pane so
                // let's update the labels and the toc backend.
-               bv->buffer().updateLabels();
+               bv->buffer().updateBuffer();
                break;
 
        case LFUN_TABULAR_INSERT:
@@ -1678,7 +1633,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                // date metrics.
                FuncRequest cmd_caption(LFUN_CAPTION_INSERT);
                doInsertInset(cur, cur.text(), cmd_caption, true, false);
-               bv->buffer().updateLabels();
+               bv->buffer().updateBuffer();
                cur.updateFlags(Update::Force);
                // FIXME: When leaving the Float (or Wrap) inset we should
                // delete any empty paragraph left above or below the
@@ -1979,7 +1934,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_ACCENT_HUNGARIAN_UMLAUT:
        case LFUN_ACCENT_CIRCLE:
        case LFUN_ACCENT_OGONEK:
-               theApp()->handleKeyFunc(cmd.action);
+               theApp()->handleKeyFunc(cmd.action());
                if (!cmd.argument().empty())
                        // FIXME: Are all these characters encoded in one byte in utf8?
                        bv->translateAndInsert(cmd.argument()[0], this, cur);
@@ -2045,6 +2000,44 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_SPELLING_ADD: {
+               docstring word = from_utf8(cmd.getArg(0));
+               Language * lang;
+               if (word.empty()) {
+                       word = cur.selectionAsString(false);
+                       // FIXME
+                       if (word.size() > 100 || word.empty()) {
+                               // Get word or selection
+                               selectWordWhenUnderCursor(cur, WHOLE_WORD);
+                               word = cur.selectionAsString(false);
+                       }
+                       lang = const_cast<Language *>(cur.getFont().language());
+               } else
+                       lang = const_cast<Language *>(languages.getLanguage(cmd.getArg(1)));
+               WordLangTuple wl(word, lang);
+               theSpellChecker()->insert(wl);
+               break;
+       }
+
+       case LFUN_SPELLING_IGNORE: {
+               docstring word = from_utf8(cmd.getArg(0));
+               Language * lang;
+               if (word.empty()) {
+                       word = cur.selectionAsString(false);
+                       // FIXME
+                       if (word.size() > 100 || word.empty()) {
+                               // Get word or selection
+                               selectWordWhenUnderCursor(cur, WHOLE_WORD);
+                               word = cur.selectionAsString(false);
+                       }
+                       lang = const_cast<Language *>(cur.getFont().language());
+               } else
+                       lang = const_cast<Language *>(languages.getLanguage(cmd.getArg(1)));
+               WordLangTuple wl(word, lang);
+               theSpellChecker()->accept(wl);
+               break;
+       }
+
        case LFUN_PARAGRAPH_PARAMS_APPLY: {
                // Given data, an encoding of the ParagraphParameters
                // generated in the Paragraph dialog, this function sets
@@ -2081,38 +2074,28 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_OUTLINE_UP:
                outline(OutlineUp, cur);
                setCursor(cur, cur.pit(), 0);
-               cur.buffer()->updateLabels();
+               cur.buffer()->updateBuffer();
                needsUpdate = true;
                break;
 
        case LFUN_OUTLINE_DOWN:
                outline(OutlineDown, cur);
                setCursor(cur, cur.pit(), 0);
-               cur.buffer()->updateLabels();
+               cur.buffer()->updateBuffer();
                needsUpdate = true;
                break;
 
        case LFUN_OUTLINE_IN:
                outline(OutlineIn, cur);
-               cur.buffer()->updateLabels();
+               cur.buffer()->updateBuffer();
                needsUpdate = true;
                break;
 
        case LFUN_OUTLINE_OUT:
                outline(OutlineOut, cur);
-               cur.buffer()->updateLabels();
-               needsUpdate = true;
-               break;
-       
-       case LFUN_OUTLINE_DRAGMOVE: {
-               int const move_id = convert<int>(cmd.getArg(0));
-               int const move_to_id = convert<int>(cmd.getArg(1));
-               dragMove(cur, move_id, move_to_id);
-               setCursor(cur, cur.pit(), 0);
-               cur.buffer()->updateLabels();
+               cur.buffer()->updateBuffer();
                needsUpdate = true;
                break;
-       }
 
        default:
                LYXERR(Debug::ACTION, "Command " << cmd << " not DISPATCHED by Text");
@@ -2171,7 +2154,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        bool enable = true;
        InsetCode code = NO_CODE;
 
-       switch (cmd.action) {
+       switch (cmd.action()) {
 
        case LFUN_DEPTH_DECREMENT:
                enable = changeDepthAllowed(cur, DEC_DEPTH);
@@ -2294,11 +2277,24 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                // not allowed in description items
                enable = !inDescriptionItem(cur);
                break;
-       case LFUN_FLOAT_LIST_INSERT:
+       case LFUN_FLOAT_LIST_INSERT: {
                code = FLOAT_LIST_CODE;
                // not allowed in description items
                enable = !inDescriptionItem(cur);
+               if (enable) {
+                       FloatList const & floats = cur.buffer()->params().documentClass().floats();
+                       FloatList::const_iterator cit = floats[to_ascii(cmd.argument())];
+                       // make sure we know about such floats
+                       if (cit == floats.end() ||
+                                       // and that we know how to generate a list of them
+                           (!cit->second.needsFloatPkg() && cit->second.listCommand().empty())) {
+                               flag.setUnknown(true);
+                               // probably not necessary, but...
+                               enable = false;
+                       }
+               }
                break;
+       }
        case LFUN_CAPTION_INSERT:
                code = CAPTION_CODE;
                // not allowed in description items
@@ -2394,6 +2390,9 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                if (cur.inTexted())
                        code = SPACE_CODE;
                break;
+       case LFUN_PREVIEW_INSERT:
+               code = PREVIEW_CODE;
+               break;
 
        case LFUN_MATH_INSERT:
        case LFUN_MATH_AMS_MATRIX:
@@ -2408,6 +2407,11 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                code = MATH_HULL_CODE;
                break;
 
+       case LFUN_REGEXP_MODE:
+               code = MATH_HULL_CODE;
+               enable = cur.buffer()->isInternal() && !cur.inRegexped();
+               break;
+
        case LFUN_INSET_MODIFY:
                // We need to disable this, because we may get called for a
                // tabular cell via
@@ -2418,31 +2422,38 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
 
        case LFUN_FONT_EMPH:
                flag.setOnOff(fontinfo.emph() == FONT_ON);
+               enable = !cur.inset().getLayout().isPassThru();
                break;
 
        case LFUN_FONT_ITAL:
                flag.setOnOff(fontinfo.shape() == ITALIC_SHAPE);
+               enable = !cur.inset().getLayout().isPassThru();
                break;
 
        case LFUN_FONT_NOUN:
                flag.setOnOff(fontinfo.noun() == FONT_ON);
+               enable = !cur.inset().getLayout().isPassThru();
                break;
 
        case LFUN_FONT_BOLD:
        case LFUN_FONT_BOLDSYMBOL:
                flag.setOnOff(fontinfo.series() == BOLD_SERIES);
+               enable = !cur.inset().getLayout().isPassThru();
                break;
 
        case LFUN_FONT_SANS:
                flag.setOnOff(fontinfo.family() == SANS_FAMILY);
+               enable = !cur.inset().getLayout().isPassThru();
                break;
 
        case LFUN_FONT_ROMAN:
                flag.setOnOff(fontinfo.family() == ROMAN_FAMILY);
+               enable = !cur.inset().getLayout().isPassThru();
                break;
 
        case LFUN_FONT_TYPEWRITER:
                flag.setOnOff(fontinfo.family() == TYPEWRITER_FAMILY);
+               enable = !cur.inset().getLayout().isPassThru();
                break;
 
        case LFUN_CUT:
@@ -2524,7 +2535,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_OUTLINE_DOWN:
        case LFUN_OUTLINE_IN:
        case LFUN_OUTLINE_OUT:
-       case LFUN_OUTLINE_DRAGMOVE:
                // FIXME: LyX is not ready for outlining within inset.
                enable = isMainText()
                        && cur.paragraph().layout().toclevel != Layout::NOT_IN_TOC;
@@ -2564,11 +2574,58 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
 
        case LFUN_LANGUAGE:
                enable = !cur.inset().getLayout().isPassThru();
+               flag.setOnOff(to_utf8(cmd.argument()) == cur.real_current_font.language()->lang());
                break;
 
        case LFUN_BREAK_PARAGRAPH:
                enable = cur.inset().getLayout().isMultiPar();
                break;
+       
+       case LFUN_SPELLING_ADD:
+       case LFUN_SPELLING_IGNORE:
+               enable = theSpellChecker();
+               break;
+
+       case LFUN_LAYOUT:
+               enable = !cur.inset().forcePlainLayout();
+               break;
+               
+       case LFUN_LAYOUT_PARAGRAPH:
+       case LFUN_PARAGRAPH_PARAMS:
+       case LFUN_PARAGRAPH_PARAMS_APPLY:
+       case LFUN_PARAGRAPH_UPDATE:
+               enable = cur.inset().allowParagraphCustomization();
+               break;
+
+       // FIXME: why are accent lfuns forbidden with pass_thru layouts?
+       case LFUN_ACCENT_ACUTE:
+       case LFUN_ACCENT_BREVE:
+       case LFUN_ACCENT_CARON:
+       case LFUN_ACCENT_CEDILLA:
+       case LFUN_ACCENT_CIRCLE:
+       case LFUN_ACCENT_CIRCUMFLEX:
+       case LFUN_ACCENT_DOT:
+       case LFUN_ACCENT_GRAVE:
+       case LFUN_ACCENT_HUNGARIAN_UMLAUT:
+       case LFUN_ACCENT_MACRON:
+       case LFUN_ACCENT_OGONEK:
+       case LFUN_ACCENT_TIE:
+       case LFUN_ACCENT_TILDE:
+       case LFUN_ACCENT_UMLAUT:
+       case LFUN_ACCENT_UNDERBAR:
+       case LFUN_ACCENT_UNDERDOT:
+       case LFUN_FONT_DEFAULT:
+       case LFUN_FONT_FRAK:
+       case LFUN_FONT_SIZE:
+       case LFUN_FONT_STATE:
+       case LFUN_FONT_UNDERLINE:
+       case LFUN_FONT_STRIKEOUT:
+       case LFUN_FONT_UULINE:
+       case LFUN_FONT_UWAVE:
+       case LFUN_TEXTSTYLE_APPLY:
+       case LFUN_TEXTSTYLE_UPDATE:
+               enable = !cur.inset().getLayout().isPassThru();
+               break;
 
        case LFUN_WORD_DELETE_FORWARD:
        case LFUN_WORD_DELETE_BACKWARD:
@@ -2599,6 +2656,15 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_WORD_LEFT_SELECT:
        case LFUN_WORD_SELECT:
        case LFUN_SECTION_SELECT:
+       case LFUN_BUFFER_BEGIN:
+       case LFUN_BUFFER_END:
+       case LFUN_BUFFER_BEGIN_SELECT:
+       case LFUN_BUFFER_END_SELECT:
+       case LFUN_INSET_BEGIN:
+       case LFUN_INSET_END:
+       case LFUN_INSET_BEGIN_SELECT:
+       case LFUN_INSET_END_SELECT:
+       case LFUN_INSET_SELECT_ALL:
        case LFUN_PARAGRAPH_UP:
        case LFUN_PARAGRAPH_DOWN:
        case LFUN_LINE_BEGIN:
@@ -2613,48 +2679,10 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_SERVER_GET_XY:
        case LFUN_SERVER_SET_XY:
        case LFUN_SERVER_GET_LAYOUT:
-       case LFUN_LAYOUT:
        case LFUN_SELF_INSERT:
-       case LFUN_FONT_DEFAULT:
-       case LFUN_FONT_UNDERLINE:
-       case LFUN_FONT_STRIKEOUT:
-       case LFUN_FONT_UULINE:
-       case LFUN_FONT_UWAVE:
-       case LFUN_FONT_SIZE:
-       case LFUN_TEXTSTYLE_APPLY:
-       case LFUN_TEXTSTYLE_UPDATE:
-       case LFUN_LAYOUT_PARAGRAPH:
-       case LFUN_PARAGRAPH_UPDATE:
-       case LFUN_ACCENT_UMLAUT:
-       case LFUN_ACCENT_CIRCUMFLEX:
-       case LFUN_ACCENT_GRAVE:
-       case LFUN_ACCENT_ACUTE:
-       case LFUN_ACCENT_TILDE:
-       case LFUN_ACCENT_CEDILLA:
-       case LFUN_ACCENT_MACRON:
-       case LFUN_ACCENT_DOT:
-       case LFUN_ACCENT_UNDERDOT:
-       case LFUN_ACCENT_UNDERBAR:
-       case LFUN_ACCENT_CARON:
-       case LFUN_ACCENT_BREVE:
-       case LFUN_ACCENT_TIE:
-       case LFUN_ACCENT_HUNGARIAN_UMLAUT:
-       case LFUN_ACCENT_CIRCLE:
-       case LFUN_ACCENT_OGONEK:
+       case LFUN_UNICODE_INSERT:
        case LFUN_THESAURUS_ENTRY:
-       case LFUN_PARAGRAPH_PARAMS_APPLY:
-       case LFUN_PARAGRAPH_PARAMS:
        case LFUN_ESCAPE:
-       case LFUN_BUFFER_BEGIN:
-       case LFUN_BUFFER_END:
-       case LFUN_BUFFER_BEGIN_SELECT:
-       case LFUN_BUFFER_END_SELECT:
-       case LFUN_INSET_BEGIN:
-       case LFUN_INSET_END:
-       case LFUN_INSET_BEGIN_SELECT:
-       case LFUN_INSET_END_SELECT:
-       case LFUN_INSET_SELECT_ALL:
-       case LFUN_UNICODE_INSERT:
                // these are handled in our dispatch()
                enable = true;
                break;
@@ -2669,48 +2697,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                || cur.paragraph().layout().pass_thru))
                enable = false;
 
-       switch (cmd.action) {
-       case LFUN_ACCENT_ACUTE:
-       case LFUN_ACCENT_BREVE:
-       case LFUN_ACCENT_CARON:
-       case LFUN_ACCENT_CEDILLA:
-       case LFUN_ACCENT_CIRCLE:
-       case LFUN_ACCENT_CIRCUMFLEX:
-       case LFUN_ACCENT_DOT:
-       case LFUN_ACCENT_GRAVE:
-       case LFUN_ACCENT_HUNGARIAN_UMLAUT:
-       case LFUN_ACCENT_MACRON:
-       case LFUN_ACCENT_OGONEK:
-       case LFUN_ACCENT_TIE:
-       case LFUN_ACCENT_TILDE:
-       case LFUN_ACCENT_UMLAUT:
-       case LFUN_ACCENT_UNDERBAR:
-       case LFUN_ACCENT_UNDERDOT:
-       case LFUN_FONT_BOLD:
-       case LFUN_FONT_BOLDSYMBOL:
-       case LFUN_FONT_TYPEWRITER:
-       case LFUN_FONT_DEFAULT:
-       case LFUN_FONT_EMPH:
-       case LFUN_FONT_NOUN:
-       case LFUN_FONT_ROMAN:
-       case LFUN_FONT_SANS:
-       case LFUN_FONT_FRAK:
-       case LFUN_FONT_ITAL:
-       case LFUN_FONT_SIZE:
-       case LFUN_FONT_STATE:
-       case LFUN_FONT_UNDERLINE:
-       case LFUN_FONT_STRIKEOUT:
-       case LFUN_FONT_UULINE:
-       case LFUN_FONT_UWAVE:
-       case LFUN_TEXTSTYLE_APPLY:
-       case LFUN_TEXTSTYLE_UPDATE:
-               if (cur.inset().getLayout().isPassThru())
-                       enable = false;
-               break;
-       default:
-               break;
-       }
-
        flag.setEnabled(enable);
        return true;
 }