X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FText3.cpp;h=da23857c1ab6c4266099449cc1da0cfd7394ddb2;hb=2abe7714078a0f772af2e3e2675d6f2b3c054e08;hp=9b66997397a1d088607a9563e9de196f568bdb75;hpb=5a58ca6576a1fa2d6bea8e9e7927d5779943e593;p=lyx.git diff --git a/src/Text3.cpp b/src/Text3.cpp index 9b66997397..da23857c1a 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -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" @@ -117,6 +118,11 @@ static void toggleAndShow(Cursor & cur, Text * text, cur.real_current_font)) text->setCursor(cur, cur.pit(), cur.pos(), false, !cur.boundary()); + if (font.language() != ignore_language) + // We need a buffer update if we change the language + // (e.g., with info insets or if the selection contains + // a par label) + cur.forceBufferUpdate(); } } @@ -237,7 +243,8 @@ static void ipaChar(Cursor & cur, InsetIPAChar::Kind kind) static bool doInsertInset(Cursor & cur, Text * text, - FuncRequest const & cmd, bool edit, bool pastesel) + FuncRequest const & cmd, bool edit, + bool pastesel, bool resetfont = false) { Buffer & buffer = cur.bv().buffer(); BufferParams const & bparams = buffer.params(); @@ -251,7 +258,7 @@ static bool doInsertInset(Cursor & cur, Text * text, cur.recordUndo(); if (cmd.action() == LFUN_ARGUMENT_INSERT) { bool cotextinsert = false; - InsetArgument const * const ia = static_cast(inset); + InsetArgument * const ia = static_cast(inset); Layout const & lay = cur.paragraph().layout(); Layout::LaTeXArgMap args = lay.args(); Layout::LaTeXArgMap::const_iterator const lait = args.find(ia->name()); @@ -274,6 +281,7 @@ static bool doInsertInset(Cursor & cur, Text * text, else ds = cur.paragraph().asString(); text->insertInset(cur, inset); + ia->init(cur.paragraph()); if (edit) inset->edit(cur, true); // Now put co-text into inset @@ -297,8 +305,11 @@ static bool doInsertInset(Cursor & cur, Text * text, * paragraph and the inset allows setting layout * FIXME: this does not work as expected when change tracking is on * However, we do not really know what to do in this case. + * FIXME: figure out a good test in the environment case (see #12251). */ - if (cur.paragraph().empty() && !inset->forcePlainLayout()) { + if (cur.paragraph().layout().isCommand() + && cur.paragraph().empty() + && !inset->forcePlainLayout()) { cur.paragraph().setPlainOrDefaultLayout(bparams.documentClass()); move_layout = true; } @@ -312,6 +323,19 @@ 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()) + : bparams.getFont(); + inset_text->setOuterFont(cur.bv(), font.fontInfo()); + } + + if (cmd.action() == LFUN_ARGUMENT_INSERT) { + InsetArgument * const ia = static_cast(inset); + ia->init(cur.paragraph()); + } + if (edit) inset->edit(cur, true); @@ -322,8 +346,14 @@ 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) { + if (resetfont) { + // Reset of font (not language) is requested. + // Used by InsetIndex (#11961). + Language const * lang = cur.getFont().language(); + Font font(bparams.getFont().fontInfo(), lang); + cur.paragraph().resetFonts(font); + } inset_text->fixParagraphsFont(); cur.pos() = 0; cur.pit() = 0; @@ -786,24 +816,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 +841,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 +866,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 +890,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); } @@ -891,14 +914,12 @@ 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 const 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 const atFirstOrLastRow = cur.atFirstOrLastRow(up); + bool const up = cmd.action() == LFUN_UP_SELECT || cmd.action() == LFUN_UP; - if (!atFirstOrLastRow) { + if (!cur.atFirstOrLastRow(up)) { needsUpdate |= cur.selHandle(select); cur.upDownInText(up, needsUpdate); needsUpdate |= cur.beforeDispatchCursor().inMathed(); @@ -914,13 +935,35 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) cur.forceBufferUpdate(); break; } + needsUpdate |= cur.selHandle(select); + bool const can_move = cur.upDownInText(up, needsUpdate); + // if the cursor can be moved up or down at an upper level, + // delegate the dispatch to next level. Otherwise, we are + // done. + if (can_move) { + cmd = FuncRequest(up ? LFUN_FINISHED_UP : LFUN_FINISHED_DOWN); + cur.undispatched(); + } + } - // if the cursor cannot be moved up or down do not remove - // the selection right now, but wait for the next dispatch. - if (select) - needsUpdate |= cur.selHandle(select); + break; + } + + case LFUN_FINISHED_UP: + case LFUN_FINISHED_DOWN: { + // move cursor up/down + bool const up = cmd.action() == LFUN_FINISHED_UP; + + if (!cur.atFirstOrLastRow(up)) { cur.upDownInText(up, needsUpdate); - cur.undispatched(); + needsUpdate |= cur.beforeDispatchCursor().inMathed(); + } else { + bool const can_move = cur.upDownInText(up, needsUpdate); + // if the cursor can be moved up or down and we are not + // moving cusor at top level, wait for the next dispatch. + // Otherwise, we are done. + if (can_move) + cur.undispatched(); } break; @@ -1001,8 +1044,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 +1068,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 +1092,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 +1116,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; } @@ -1502,7 +1537,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) pasteFromStack(cur, bv->buffer().errorList("Paste"), 0); else if (theClipboard().hasTextContents()) { if (pasteClipboardText(cur, bv->buffer().errorList("Paste"), - true, Clipboard::AnyTextType)) + !cur.paragraph().parbreakIsNewline(), + Clipboard::AnyTextType)) tryGraphics = false; } if (tryGraphics && theClipboard().hasGraphicsContents()) @@ -1838,8 +1874,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) bvcur.resetAnchor(); if (!bv->mouseSetCursor(cur, cmd.modifier() == ShiftModifier)) cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor); - if (bvcur.wordSelection()) - selectWord(bvcur, WHOLE_WORD); + // FIXME: move this to mouseSetCursor? + if (bvcur.wordSelection() && bvcur.inTexted()) + expandWordSel(bvcur); break; case mouse_button::button2: @@ -1907,6 +1944,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // We continue with our existing selection or start a new one, so don't // reset the anchor. bvcur.setCursor(cur); + if (bvcur.wordSelection() && bvcur.inTexted()) + expandWordSel(bvcur); bvcur.selection(true); bvcur.setCurrentFont(); if (cur.top() == old) { @@ -2077,22 +2116,19 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_INDEX_INSERT: case LFUN_PREVIEW_INSERT: case LFUN_SCRIPT_INSERT: - case LFUN_IPA_INSERT: + case LFUN_IPA_INSERT: { + // Indexes reset font formatting (#11961) + bool const resetfont = cmd.action() == LFUN_INDEX_INSERT; // Open the inset, and move the current selection // inside it. - doInsertInset(cur, this, cmd, true, true); + doInsertInset(cur, this, cmd, true, true, resetfont); cur.posForward(); - /* The font of the inset is computed 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 correct. 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. cur.forceBufferUpdate(); break; + } case LFUN_FLEX_INSERT: { // Open the inset, and move the current selection @@ -2115,6 +2151,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // leave this now in order to insert the next one. if (inautoarg) { cur.leaveInset(cur.inset()); + cur.setCurrentFont(); cur.posForward(); if (arg.insertonnewline && cur.pos() > 0) { FuncRequest cmd2(LFUN_PARAGRAPH_BREAK); @@ -2474,6 +2511,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()); @@ -2495,10 +2539,6 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) selectWordWhenUnderCursor(cur, WHOLE_WORD_STRICT); Font font(ignore_font, lang); toggleAndShow(cur, this, font, toggle); - // We need a buffer update if we change the language - // of an info inset - if (cur.insetInSelection(INFO_CODE)) - cur.forceBufferUpdate(); break; } @@ -2533,10 +2573,6 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) freeFonts.push(make_pair(props, font)); toggleall = toggle; toggleAndShow(cur, this, font, toggleall); - // We need a buffer update if we change the language - // of an info inset - if (cur.insetInSelection(INFO_CODE)) - cur.forceBufferUpdate(); cur.message(bformat(_("Text properties applied: %1$s"), props)); } else LYXERR0("Invalid argument of textstyle-update"); @@ -2670,8 +2706,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); @@ -2716,6 +2759,65 @@ 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 of whole buffer + bv->buffer().requestSpellcheck(); + } + 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::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 of whole buffer + bv->buffer().requestSpellcheck(); + } + break; + } + + case LFUN_SPELLING_IGNORE: { Language const * language = getLanguage(cur, cmd.getArg(1)); docstring word = from_utf8(cmd.getArg(0)); @@ -2813,32 +2915,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(cur.buffer()->wordCount())); - } else if (arg0 == "chars") { - cur.message(convert(cur.buffer()->charCount(false))); - } else if (arg0 == "chars-space") { - cur.message(convert(cur.buffer()->charCount(true))); - } else { - cur.message(convert(cur.buffer()->wordCount()) + " " - + convert(cur.buffer()->charCount(false)) + " " - + convert(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(cur.buffer()->wordCount())); + } else if (arg0 == "chars") { + cur.message(convert(cur.buffer()->charCount(false))); + } else if (arg0 == "chars-space") { + cur.message(convert(cur.buffer()->charCount(true))); + } else { + cur.message(convert(cur.buffer()->wordCount()) + " " + + convert(cur.buffer()->charCount(false)) + " " + + convert(cur.buffer()->charCount(true))); } break; + } default: LYXERR(Debug::ACTION, "Command " << cmd << " not DISPATCHED by Text"); @@ -2943,6 +3044,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") @@ -3079,15 +3182,22 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, break; case LFUN_FLEX_INSERT: { code = FLEX_CODE; - string s = cmd.getArg(0); - InsetLayout il = - cur.buffer()->params().documentClass().insetLayout(from_utf8(s)); - if (il.lyxtype() != InsetLyXType::CHARSTYLE && - il.lyxtype() != InsetLyXType::CUSTOM && - il.lyxtype ()!= InsetLyXType::STANDARD) + docstring s = from_utf8(cmd.getArg(0)); + // Prepend "Flex:" prefix if not there + if (!prefixIs(s, from_ascii("Flex:"))) + s = from_ascii("Flex:") + s; + if (!cur.buffer()->params().documentClass().hasInsetLayout(s)) enable = false; - break; + else { + InsetLyXType ilt = + cur.buffer()->params().documentClass().insetLayout(s).lyxtype(); + if (ilt != InsetLyXType::CHARSTYLE + && ilt != InsetLyXType::CUSTOM + && ilt != InsetLyXType::STANDARD) + enable = false; } + break; + } case LFUN_BOX_INSERT: code = BOX_CODE; break; @@ -3342,6 +3452,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, break; case LFUN_PRIMARY_SELECTION_PASTE: + status.setUnknown(!theSelection().supported()); enable = cur.selection() || !theSelection().empty(); break; @@ -3446,6 +3557,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; @@ -3462,8 +3575,10 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, docstring const req_layout = ignoreautonests ? from_utf8(cmd.getArg(0)) : cmd.argument(); docstring const layout = resolveLayout(req_layout, cur); - enable = !owner_->forcePlainLayout() && !layout.empty(); - status.setOnOff(isAlreadyLayout(layout, cur)); + // FIXME: make this work in multicell selection case + enable = !owner_->forcePlainLayout() && !layout.empty() && !cur.selIsMultiCell(); + status.setOnOff(!owner_->forcePlainLayout() && !cur.selIsMultiCell() + && isAlreadyLayout(layout, cur)); break; } @@ -3543,6 +3658,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;