]> git.lyx.org Git - features.git/blobdiff - src/Text3.cpp
Always remove selection after cursor left/right
[features.git] / src / Text3.cpp
index 1d2f5618eaffe19e42cb37bd5c79c333d647ce79..ffc5d758dfaac80af426c07403a0e73d4de0a843 100644 (file)
@@ -67,6 +67,7 @@
 
 #include "support/convert.h"
 #include "support/debug.h"
+#include "support/docstring_list.h"
 #include "support/filetools.h"
 #include "support/gettext.h"
 #include "support/lassert.h"
@@ -312,6 +313,14 @@ static bool doInsertInset(Cursor & cur, Text * text,
        }
        text->insertInset(cur, inset);
 
+       InsetText * inset_text = inset->asInsetText();
+       if (inset_text) {
+               Font const & font = inset->inheritFont()
+                       ? cur.bv().textMetrics(text).displayFont(cur.pit(), cur.pos())
+                       : buffer.params().getFont();
+               inset_text->setOuterFont(cur.bv(), font.fontInfo());
+       }
+
        if (edit)
                inset->edit(cur, true);
 
@@ -322,7 +331,6 @@ static bool doInsertInset(Cursor & cur, Text * text,
        cur.buffer()->errors("Paste");
        cur.clearSelection(); // bug 393
        cur.finishUndo();
-       InsetText * inset_text = inset->asInsetText();
        if (inset_text) {
                inset_text->fixParagraphsFont();
                cur.pos() = 0;
@@ -786,24 +794,20 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                bool const cur_moved = cursorForward(cur);
                needsUpdate |= cur_moved;
 
-               if (!cur_moved && oldTopSlice == cur.top()
-                              && cur.boundary() == oldBoundary) {
+               if (!cur_moved && cur.depth() > 1
+                    && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) {
                        cur.undispatched();
                        cmd = FuncRequest(LFUN_FINISHED_FORWARD);
 
-                       // we will probably be moving out the inset, so we should execute
-                       // the depm-mechanism, but only when the cursor has a place to
-                       // go outside this inset, i.e. in a slice above.
-                       if (cur.depth() > 1 && cur.pos() == cur.lastpos()
-                                 && cur.pit() == cur.lastpit()) {
-                               // The cursor hasn't changed yet. To give the
-                               // DEPM the possibility of doing something we must
-                               // provide it with two different cursors.
-                               Cursor dummy = cur;
-                               dummy.pos() = dummy.pit() = 0;
-                               if (cur.bv().checkDepm(dummy, cur))
-                                       cur.forceBufferUpdate();
-                       }
+                       // we will be moving out the inset, so we should execute
+                       // the depm-mechanism.
+                       // The cursor hasn't changed yet. To give the DEPM the
+                       // possibility of doing something we must provide it with
+                       // two different cursors.
+                       Cursor dummy = cur;
+                       dummy.pos() = dummy.pit() = 0;
+                       if (cur.bv().checkDepm(dummy, cur))
+                               cur.forceBufferUpdate();
                }
                break;
        }
@@ -815,24 +819,21 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                bool const cur_moved = cursorBackward(cur);
                needsUpdate |= cur_moved;
 
-               if (!cur_moved && oldTopSlice == cur.top()
-                              && cur.boundary() == oldBoundary) {
+               if (!cur_moved && cur.depth() > 1
+                    && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) {
                        cur.undispatched();
                        cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
 
-                       // we will probably be moving out the inset, so we should execute
-                       // the depm-mechanism, but only when the cursor has a place to
-                       // go outside this inset, i.e. in a slice above.
-                       if (cur.depth() > 1 && cur.pos() == 0 && cur.pit() == 0) {
-                               // The cursor hasn't changed yet. To give the
-                               // DEPM the possibility of doing something we must
-                               // provide it with two different cursors.
-                               Cursor dummy = cur;
-                               dummy.pos() = cur.lastpos();
-                               dummy.pit() = cur.lastpit();
-                               if (cur.bv().checkDepm(dummy, cur))
-                                       cur.forceBufferUpdate();
-                       }
+                       // we will be moving out the inset, so we should execute
+                       // the depm-mechanism.
+                       // The cursor hasn't changed yet. To give the DEPM the
+                       // possibility of doing something we must provide it with
+                       // two different cursors.
+                       Cursor dummy = cur;
+                       dummy.pos() = cur.lastpos();
+                       dummy.pit() = cur.lastpit();
+                       if (cur.bv().checkDepm(dummy, cur))
+                               cur.forceBufferUpdate();
                }
                break;
        }
@@ -843,8 +844,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        needsUpdate |= cur.selHandle(act == LFUN_CHAR_LEFT_SELECT);
                        bool const cur_moved = cursorVisLeft(cur);
                        needsUpdate |= cur_moved;
-                       if (!cur_moved && oldTopSlice == cur.top()
-                                      && cur.boundary() == oldBoundary) {
+                       if (!cur_moved && cur.depth() > 1
+                            && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) {
                                cur.undispatched();
                                cmd = FuncRequest(LFUN_FINISHED_LEFT);
                        }
@@ -867,8 +868,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        needsUpdate |= cur.selHandle(cmd.action() == LFUN_CHAR_RIGHT_SELECT);
                        bool const cur_moved = cursorVisRight(cur);
                        needsUpdate |= cur_moved;
-                       if (!cur_moved && oldTopSlice == cur.top()
-                                      && cur.boundary() == oldBoundary) {
+                       if (!cur_moved && cur.depth() > 1
+                            && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) {
                                cur.undispatched();
                                cmd = FuncRequest(LFUN_FINISHED_RIGHT);
                        }
@@ -1001,8 +1002,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_RIGHT_SELECT);
                        bool const cur_moved = cursorVisRightOneWord(cur);
                        needsUpdate |= cur_moved;
-                       if (!cur_moved && oldTopSlice == cur.top()
-                                      && cur.boundary() == oldBoundary) {
+                       if (!cur_moved && cur.depth() > 1
+                            && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) {
                                cur.undispatched();
                                cmd = FuncRequest(LFUN_FINISHED_RIGHT);
                        }
@@ -1025,24 +1026,20 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                bool const cur_moved = cursorForwardOneWord(cur);
                needsUpdate |= cur_moved;
 
-               if (!cur_moved && oldTopSlice == cur.top()
-                              && cur.boundary() == oldBoundary) {
+               if (!cur_moved && cur.depth() > 1
+                    && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) {
                        cur.undispatched();
                        cmd = FuncRequest(LFUN_FINISHED_FORWARD);
 
-                       // we will probably be moving out the inset, so we should execute
-                       // the depm-mechanism, but only when the cursor has a place to
-                       // go outside this inset, i.e. in a slice above.
-                       if (cur.depth() > 1 && cur.pos() == cur.lastpos()
-                                 && cur.pit() == cur.lastpit()) {
-                               // The cursor hasn't changed yet. To give the
-                               // DEPM the possibility of doing something we must
-                               // provide it with two different cursors.
-                               Cursor dummy = cur;
-                               dummy.pos() = dummy.pit() = 0;
-                               if (cur.bv().checkDepm(dummy, cur))
-                                       cur.forceBufferUpdate();
-                       }
+                       // we will be moving out the inset, so we should execute
+                       // the depm-mechanism.
+                       // The cursor hasn't changed yet. To give the DEPM the
+                       // possibility of doing something we must provide it with
+                       // two different cursors.
+                       Cursor dummy = cur;
+                       dummy.pos() = dummy.pit() = 0;
+                       if (cur.bv().checkDepm(dummy, cur))
+                               cur.forceBufferUpdate();
                }
                break;
        }
@@ -1053,8 +1050,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_LEFT_SELECT);
                        bool const cur_moved = cursorVisLeftOneWord(cur);
                        needsUpdate |= cur_moved;
-                       if (!cur_moved && oldTopSlice == cur.top()
-                                      && cur.boundary() == oldBoundary) {
+                       if (!cur_moved && cur.depth() > 1
+                            && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) {
                                cur.undispatched();
                                cmd = FuncRequest(LFUN_FINISHED_LEFT);
                        }
@@ -1077,25 +1074,21 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                bool const cur_moved = cursorBackwardOneWord(cur);
                needsUpdate |= cur_moved;
 
-               if (!cur_moved && oldTopSlice == cur.top()
-                              && cur.boundary() == oldBoundary) {
+               if (!cur_moved && cur.depth() > 1
+                    && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) {
                        cur.undispatched();
                        cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
 
-                       // we will probably be moving out the inset, so we should execute
-                       // the depm-mechanism, but only when the cursor has a place to
-                       // go outside this inset, i.e. in a slice above.
-                       if (cur.depth() > 1 && cur.pos() == 0
-                                 && cur.pit() == 0) {
-                               // The cursor hasn't changed yet. To give the
-                               // DEPM the possibility of doing something we must
-                               // provide it with two different cursors.
-                               Cursor dummy = cur;
-                               dummy.pos() = cur.lastpos();
-                               dummy.pit() = cur.lastpit();
-                               if (cur.bv().checkDepm(dummy, cur))
-                                       cur.forceBufferUpdate();
-                       }
+                       // we will be moving out the inset, so we should execute
+                       // the depm-mechanism.
+                       // The cursor hasn't changed yet. To give the DEPM the
+                       // possibility of doing something we must provide it with
+                       // two different cursors.
+                       Cursor dummy = cur;
+                       dummy.pos() = cur.lastpos();
+                       dummy.pit() = cur.lastpit();
+                       if (cur.bv().checkDepm(dummy, cur))
+                               cur.forceBufferUpdate();
                }
                break;
        }
@@ -1370,6 +1363,14 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_INSET_SPLIT: {
+               if (splitInset(cur)) {
+                       needsUpdate = true;
+                       cur.forceBufferUpdate();
+               }
+               break;
+       }
+
        case LFUN_GRAPHICS_SET_GROUP: {
                InsetGraphics * ins = graphics::getCurrentGraphicsInset(cur);
                if (!ins)
@@ -1540,11 +1541,6 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                cur.message(_("Cut"));
                break;
 
-       case LFUN_COPY:
-               copySelection(cur);
-               cur.message(_("Copy"));
-               break;
-
        case LFUN_SERVER_GET_XY:
                cur.message(from_utf8(
                        convert<string>(tm->cursorX(cur.top(), cur.boundary()))
@@ -1637,7 +1633,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                if (para.layout().isEnvironment())
                        layout = para.layout().name();
                depth_type split_depth = cur.paragraph().params().depth();
-               depth_type nextpar_depth = 0;
+               vector<depth_type> nextpars_depth;
                if (outer || previous) {
                        // check if we have an environment in our scope
                        pit_type pit = cur.pit();
@@ -1662,9 +1658,20 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        }
                }
                if ((outer || normal) && cur.pit() < cur.lastpit()) {
-                       // save nesting of following paragraph
-                       Paragraph cpar = pars_[cur.pit() + 1];
-                       nextpar_depth = cpar.params().depth();
+                       // save nesting of following paragraphs if they are deeper
+                       // or same depth
+                       pit_type offset = 1;
+                       depth_type cur_depth = pars_[cur.pit()].params().depth();
+                       while (cur.pit() + offset <= cur.lastpit()) {
+                               Paragraph cpar = pars_[cur.pit() + offset];
+                               depth_type nextpar_depth = cpar.params().depth();
+                               if (cur_depth <= nextpar_depth && nextpar_depth > 0) {
+                                       nextpars_depth.push_back(nextpar_depth);
+                                       cur_depth = nextpar_depth;
+                                       ++offset;
+                               } else
+                                       break;
+                       }
                }
                if (before)
                        cur.top().setPitPos(cur.pit(), 0);
@@ -1692,17 +1699,20 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                else
                        lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse"));
                lyx::dispatch(FuncRequest(LFUN_LAYOUT, layout));
-               if ((outer || normal) && nextpar_depth > 0) {
-                       // restore nesting of following paragraph
+               if ((outer || normal) && !nextpars_depth.empty()) {
+                       // restore nesting of following paragraphs
                        DocIterator scur = cur;
-                       depth_type const max_depth = cur.paragraph().params().depth() + 1;
-                       cur.forwardPar();
-                       while (cur.paragraph().params().depth() < min(nextpar_depth, max_depth)) {
-                               depth_type const olddepth = cur.paragraph().params().depth();
-                               lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT));
-                               if (olddepth == cur.paragraph().params().depth())
-                                       // leave loop if no incrementation happens
-                                       break;
+                       depth_type max_depth = cur.paragraph().params().depth() + 1;
+                       for (auto nextpar_depth : nextpars_depth) {
+                               cur.forwardPar();
+                               while (cur.paragraph().params().depth() < min(nextpar_depth, max_depth)) {
+                                       depth_type const olddepth = cur.paragraph().params().depth();
+                                       lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT));
+                                       if (olddepth == cur.paragraph().params().depth())
+                                               // leave loop if no incrementation happens
+                                               break;
+                               }
+                               max_depth = cur.paragraph().params().depth() + 1;
                        }
                        cur.setCursor(scur);
                }
@@ -1840,7 +1850,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        // Don't do anything if we right-click a
                        // selection, a context menu will popup.
                        if (bvcur.selection() && cur >= bvcur.selectionBegin()
-                           && cur < bvcur.selectionEnd()) {
+                           && cur <= bvcur.selectionEnd()) {
                                cur.noScreenUpdate();
                                return;
                        }
@@ -2065,15 +2075,6 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                // inside it.
                doInsertInset(cur, this, cmd, true, true);
                cur.posForward();
-               if (act == LFUN_SCRIPT_INSERT) {
-                       /* Script insets change the font style in metrics(), and
-                        * this is used to compute the height of the caret
-                        * (because the font is stored in TextMetrics::font_).
-                        * When we insert, we have to make sure that metrics are
-                        * computed so that the caret height is wrong. Arguably,
-                        * this is hackish.*/
-                       bv->processUpdateFlags(Update::SinglePar);
-               }
                cur.setCurrentFont();
                // Some insets are numbered, others are shown in the outline pane so
                // let's update the labels and the toc backend.
@@ -2143,7 +2144,6 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                // Unknown style. Report and fall back to default.
                                cur.errorMessage(from_utf8(N_("Table Style ")) + from_utf8(tabstyle) +
                                                     from_utf8(N_(" not known")));
-                       
                }
                if (doInsertInset(cur, this, cmd, false, true))
                        cur.posForward();
@@ -2159,7 +2159,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        break;
                int const r = convert<int>(rows);
                int const c = convert<int>(cols);
-                       
+
                string suffix;
                if (r == 1)
                        suffix = "_1x1";
@@ -2253,7 +2253,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_NOMENCL_INSERT: {
                InsetCommandParams p(NOMENCL_CODE);
                if (cmd.argument().empty()) {
-                       p["symbol"] = 
+                       p["symbol"] =
                                bv->cursor().innerText()->getStringForDialog(bv->cursor());
                        cur.clearSelection();
                } else
@@ -2461,6 +2461,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_FONT_NO_SPELLCHECK: {
+               Font font(ignore_font, ignore_language);
+               font.fontInfo().setNoSpellcheck(FONT_TOGGLE);
+               toggleAndShow(cur, this, font);
+               break;
+       }
+
        case LFUN_FONT_SIZE: {
                Font font(ignore_font, ignore_language);
                setLyXSize(to_utf8(cmd.argument()), font.fontInfo());
@@ -2657,8 +2664,15 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                docstring arg = cmd.argument();
                if (arg.empty()) {
                        arg = cur.selectionAsString(false);
-                       // FIXME
+                       // Too large. We unselect if needed and try to get
+                       // the first word in selection or under cursor
                        if (arg.size() > 100 || arg.empty()) {
+                               if (cur.selection()) {
+                                       DocIterator selbeg = cur.selectionBegin();
+                                       cur.clearSelection();
+                                       setCursorIntern(cur, selbeg.pit(), selbeg.pos());
+                                       cur.screenUpdateFlags(Update::Force);
+                               }
                                // Get word or selection
                                selectWordWhenUnderCursor(cur, WHOLE_WORD);
                                arg = cur.selectionAsString(false);
@@ -2703,6 +2717,75 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_SPELLING_ADD_LOCAL: {
+               Language const * language = getLanguage(cur, cmd.getArg(1));
+               docstring word = from_utf8(cmd.getArg(0));
+               if (word.empty()) {
+                       word = cur.selectionAsString(false);
+                       if (word.size() > 100)
+                               break;
+                       if (word.empty()) {
+                               // Get word or selection
+                               selectWordWhenUnderCursor(cur, WHOLE_WORD);
+                               word = cur.selectionAsString(false);
+                       }
+               }
+               WordLangTuple wl(word, language);
+               if (!bv->buffer().params().spellignored(wl)) {
+                       cur.recordUndoBufferParams();
+                       bv->buffer().params().spellignore().push_back(wl);
+                       cur.recordUndo();
+                       // trigger re-check
+                       WordLangTuple wl;
+                       docstring_list suggestions;
+                       Paragraph const & par = cur.paragraph();
+                       pos_type from = cur.pos();
+                       pos_type to = from;
+                       par.spellCheck(from, to, wl, suggestions, true, true);
+               }
+               break;
+       }
+
+       case LFUN_SPELLING_REMOVE_LOCAL: {
+               Language const * language = getLanguage(cur, cmd.getArg(1));
+               docstring word = from_utf8(cmd.getArg(0));
+               if (word.empty()) {
+                       word = cur.selectionAsString(false);
+                       if (word.size() > 100)
+                               break;
+                       if (word.empty()) {
+                               // Get word or selection
+                               selectWordWhenUnderCursor(cur, WHOLE_WORD);
+                               word = cur.selectionAsString(false);
+                       }
+               }
+               WordLangTuple wl(word, language);
+               bool has_item = false;
+               vector<WordLangTuple>::const_iterator it = bv->buffer().params().spellignore().begin();
+               for (; it != bv->buffer().params().spellignore().end(); ++it) {
+                       if (it->lang()->code() != wl.lang()->code())
+                               continue;
+                       if (it->word() == wl.word()) {
+                               has_item = true;
+                               break;
+                       }
+               }
+               if (has_item) {
+                       cur.recordUndoBufferParams();
+                       bv->buffer().params().spellignore().erase(it);
+                       cur.recordUndo();
+                       // trigger re-check
+                       WordLangTuple wl;
+                       docstring_list suggestions;
+                       Paragraph const & par = cur.paragraph();
+                       pos_type from = cur.pos();
+                       pos_type to = from;
+                       par.spellCheck(from, to, wl, suggestions, true, true);
+               }
+               break;
+       }
+
+
        case LFUN_SPELLING_IGNORE: {
                Language const * language = getLanguage(cur, cmd.getArg(1));
                docstring word = from_utf8(cmd.getArg(0));
@@ -2800,32 +2883,31 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                needsUpdate = true;
                break;
 
-       case LFUN_SERVER_GET_STATISTICS:
-               {
-                       DocIterator from, to;
-                       if (cur.selection()) {
-                               from = cur.selectionBegin();
-                               to = cur.selectionEnd();
-                       } else {
-                               from = doc_iterator_begin(cur.buffer());
-                               to = doc_iterator_end(cur.buffer());
-                       }
-
-                       cur.buffer()->updateStatistics(from, to);
-                       string const arg0 = cmd.getArg(0);
-                       if (arg0 == "words") {
-                               cur.message(convert<docstring>(cur.buffer()->wordCount()));
-                       } else if (arg0 == "chars") {
-                               cur.message(convert<docstring>(cur.buffer()->charCount(false)));
-                       } else if (arg0 == "chars-space") {
-                               cur.message(convert<docstring>(cur.buffer()->charCount(true)));
-                       } else {
-                               cur.message(convert<docstring>(cur.buffer()->wordCount()) + " "
-                               + convert<docstring>(cur.buffer()->charCount(false)) + " "
-                               + convert<docstring>(cur.buffer()->charCount(true)));
-                       }
+       case LFUN_SERVER_GET_STATISTICS: {
+               DocIterator from, to;
+               if (cur.selection()) {
+                       from = cur.selectionBegin();
+                       to = cur.selectionEnd();
+               } else {
+                       from = doc_iterator_begin(cur.buffer());
+                       to = doc_iterator_end(cur.buffer());
+               }
+
+               cur.buffer()->updateStatistics(from, to);
+               string const arg0 = cmd.getArg(0);
+               if (arg0 == "words") {
+                       cur.message(convert<docstring>(cur.buffer()->wordCount()));
+               } else if (arg0 == "chars") {
+                       cur.message(convert<docstring>(cur.buffer()->charCount(false)));
+               } else if (arg0 == "chars-space") {
+                       cur.message(convert<docstring>(cur.buffer()->charCount(true)));
+               } else {
+                       cur.message(convert<docstring>(cur.buffer()->wordCount()) + " "
+                       + convert<docstring>(cur.buffer()->charCount(false)) + " "
+                       + convert<docstring>(cur.buffer()->charCount(true)));
                }
                break;
+       }
 
        default:
                LYXERR(Debug::ACTION, "Command " << cmd << " not DISPATCHED by Text");
@@ -2898,7 +2980,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        bool enable = true;
        bool allow_in_passthru = false;
        InsetCode code = NO_CODE;
-       
+
        switch (cmd.action()) {
 
        case LFUN_DEPTH_DECREMENT:
@@ -2930,6 +3012,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                        code = BRANCH_CODE;
                else if (cmd.argument() == "citation")
                        code = CITE_CODE;
+               else if (cmd.argument() == "counter")
+                       code = COUNTER_CODE;
                else if (cmd.argument() == "ert")
                        code = ERT_CODE;
                else if (cmd.argument() == "external")
@@ -3069,9 +3153,9 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                string s = cmd.getArg(0);
                InsetLayout il =
                        cur.buffer()->params().documentClass().insetLayout(from_utf8(s));
-               if (il.lyxtype() != InsetLayout::CHARSTYLE &&
-                   il.lyxtype() != InsetLayout::CUSTOM &&
-                   il.lyxtype ()!= InsetLayout::STANDARD)
+               if (il.lyxtype() != InsetLyXType::CHARSTYLE &&
+                   il.lyxtype() != InsetLyXType::CUSTOM &&
+                   il.lyxtype ()!= InsetLyXType::STANDARD)
                        enable = false;
                break;
                }
@@ -3263,7 +3347,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                break;
 
        case LFUN_CUT:
-       case LFUN_COPY:
                enable = cur.selection();
                break;
 
@@ -3434,6 +3517,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                break;
 
        case LFUN_SPELLING_ADD:
+       case LFUN_SPELLING_ADD_LOCAL:
+       case LFUN_SPELLING_REMOVE_LOCAL:
        case LFUN_SPELLING_IGNORE:
        case LFUN_SPELLING_REMOVE:
                enable = theSpellChecker() != nullptr;
@@ -3451,7 +3536,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                docstring const layout = resolveLayout(req_layout, cur);
 
                enable = !owner_->forcePlainLayout() && !layout.empty();
-               status.setOnOff(isAlreadyLayout(layout, cur));
+               status.setOnOff(!owner_->forcePlainLayout() && isAlreadyLayout(layout, cur));
                break;
        }
 
@@ -3531,6 +3616,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_FONT_CROSSOUT:
        case LFUN_FONT_UNDERUNDERLINE:
        case LFUN_FONT_UNDERWAVE:
+       case LFUN_FONT_NO_SPELLCHECK:
        case LFUN_TEXTSTYLE_UPDATE:
                enable = !cur.paragraph().isPassThru();
                break;