X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FText3.cpp;h=36739a8e1e21c732226dd15b5afb85c25d1c2125;hb=d706a2a291c5d2bae141010d9f161098ed6beb6a;hp=ee0902a87a7cc5a54c3f3126a75dfb07938d01c6;hpb=7e72c1d0d31c2b3155c4767f830cc861716ba357;p=lyx.git diff --git a/src/Text3.cpp b/src/Text3.cpp index ee0902a87a..36739a8e1e 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -53,7 +53,7 @@ #include "frontends/Selection.h" #include "insets/InsetArgument.h" -#include "insets/InsetCollapsable.h" +#include "insets/InsetCollapsible.h" #include "insets/InsetCommand.h" #include "insets/InsetExternal.h" #include "insets/InsetFloat.h" @@ -78,7 +78,7 @@ #include "support/regex.h" #include "mathed/InsetMathHull.h" -#include "mathed/MathMacroTemplate.h" +#include "mathed/InsetMathMacroTemplate.h" #include #include @@ -90,13 +90,16 @@ namespace lyx { using cap::copySelection; using cap::cutSelection; +using cap::cutSelectionToTemp; using cap::pasteFromStack; +using cap::pasteFromTemp; using cap::pasteClipboardText; using cap::pasteClipboardGraphics; using cap::replaceSelection; using cap::grabAndEraseSelection; using cap::selClearOrDel; using cap::pasteSimpleText; +using frontend::Clipboard; // globals... static Font freefont(ignore_font, ignore_language); @@ -178,7 +181,7 @@ static void mathDispatch(Cursor & cur, FuncRequest const & cmd) LASSERT(cur.inMathed(), return); cur.pos() = 0; cur.resetAnchor(); - cur.setSelection(true); + cur.selection(true); cur.pos() = cur.lastpos(); if (cmd.action() != LFUN_MATH_MODE) // LFUN_MATH_MODE has a different meaning in math mode @@ -242,7 +245,7 @@ static bool doInsertInset(Cursor & cur, Text * text, if (!inset) return false; - if (InsetCollapsable * ci = inset->asInsetCollapsable()) + if (InsetCollapsible * ci = inset->asInsetCollapsible()) ci->setButtonLabel(); cur.recordUndo(); @@ -298,7 +301,7 @@ static bool doInsertInset(Cursor & cur, Text * text, bool gotsel = false; if (cur.selection()) { - cutSelection(cur, false, pastesel); + cutSelectionToTemp(cur, false, pastesel); cur.clearSelection(); gotsel = true; } @@ -310,7 +313,7 @@ static bool doInsertInset(Cursor & cur, Text * text, if (!gotsel || !pastesel) return true; - pasteFromStack(cur, cur.buffer()->errorList("Paste"), 0); + pasteFromTemp(cur, cur.buffer()->errorList("Paste")); cur.buffer()->errors("Paste"); cur.clearSelection(); // bug 393 cur.finishUndo(); @@ -363,7 +366,23 @@ enum OutlineOp { }; -static void outline(OutlineOp mode, Cursor & cur) +static void insertSeparator(Cursor & cur, depth_type const depth) +{ + Buffer & buf = *cur.buffer(); + lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK)); + DocumentClass const & tc = buf.params().documentClass(); + lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"") + tc.plainLayout().name() + + from_ascii("\" ignoreautonests"))); + // FIXME: Bibitem mess! + if (cur.prevInset() && cur.prevInset()->lyxCode() == BIBITEM_CODE) + lyx::dispatch(FuncRequest(LFUN_CHAR_DELETE_BACKWARD)); + lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain")); + while (cur.paragraph().params().depth() > depth) + lyx::dispatch(FuncRequest(LFUN_DEPTH_DECREMENT)); +} + + +static void outline(OutlineOp mode, Cursor & cur, Text * text) { Buffer & buf = *cur.buffer(); pit_type & pit = cur.pit(); @@ -374,6 +393,7 @@ static void outline(OutlineOp mode, Cursor & cur) // The final paragraph of area to be copied: ParagraphList::iterator finish = start; ParagraphList::iterator const end = pars.end(); + depth_type const current_depth = cur.paragraph().params().depth(); int const thistoclevel = buf.text().getTocLevel(distance(bgn, start)); int toclevel; @@ -408,10 +428,47 @@ static void outline(OutlineOp mode, Cursor & cur) // Not found; do nothing if (toclevel == Layout::NOT_IN_TOC || toclevel > thistoclevel) return; - pit_type const newpit = distance(bgn, dest); + pit_type newpit = distance(bgn, dest); pit_type const len = distance(start, finish); pit_type const deletepit = pit + len; buf.undo().recordUndo(cur, newpit, deletepit - 1); + // If we move an environment upwards, make sure it is + // separated from its new neighbour below: + // If an environment of the same layout follows, and the moved + // paragraph sequence does not end with a separator, insert one. + ParagraphList::iterator lastmoved = finish; + --lastmoved; + if (start->layout().isEnvironment() + && dest->layout() == start->layout() + && !lastmoved->isEnvSeparator(lastmoved->beginOfBody())) { + cur.pit() = distance(bgn, lastmoved); + cur.pos() = cur.lastpos(); + insertSeparator(cur, current_depth); + cur.pit() = pit; + } + // Likewise, if we moved an environment upwards, make sure it + // is separated from its new neighbour above. + // The paragraph before the target of movement + if (dest != bgn) { + ParagraphList::iterator before = dest; + --before; + // Get the parent paragraph (outer in nested context) + pit_type const parent = + before->params().depth() > current_depth + ? text->depthHook(distance(bgn, before), current_depth) + : distance(bgn, before); + // If a environment with same layout preceeds the moved one in the new + // position, and there is no separator yet, insert one. + if (start->layout().isEnvironment() + && pars[parent].layout() == start->layout() + && !before->isEnvSeparator(before->beginOfBody())) { + cur.pit() = distance(bgn, before); + cur.pos() = cur.lastpos(); + insertSeparator(cur, current_depth); + cur.pit() = pit; + } + } + newpit = distance(bgn, dest); pars.splice(dest, start, finish); cur.pit() = newpit; break; @@ -429,9 +486,45 @@ static void outline(OutlineOp mode, Cursor & cur) && toclevel <= thistoclevel) break; } - // One such was found: + // One such was found, so go on... + // If we move an environment downwards, make sure it is + // separated from its new neighbour above. pit_type newpit = distance(bgn, dest); buf.undo().recordUndo(cur, pit, newpit - 1); + // The paragraph before the target of movement + ParagraphList::iterator before = dest; + --before; + // Get the parent paragraph (outer in nested context) + pit_type const parent = + before->params().depth() > current_depth + ? text->depthHook(distance(bgn, before), current_depth) + : distance(bgn, before); + // If a environment with same layout preceeds the moved one in the new + // position, and there is no separator yet, insert one. + if (start->layout().isEnvironment() + && pars[parent].layout() == start->layout() + && !before->isEnvSeparator(before->beginOfBody())) { + cur.pit() = distance(bgn, before); + cur.pos() = cur.lastpos(); + insertSeparator(cur, current_depth); + cur.pit() = pit; + } + // Likewise, make sure moved environments are separated + // from their new neighbour below: + // If an environment of the same layout follows, and the moved + // paragraph sequence does not end with a separator, insert one. + ParagraphList::iterator lastmoved = finish; + --lastmoved; + if (dest != end + && start->layout().isEnvironment() + && dest->layout() == start->layout() + && !lastmoved->isEnvSeparator(lastmoved->beginOfBody())) { + cur.pit() = distance(bgn, lastmoved); + cur.pos() = cur.lastpos(); + insertSeparator(cur, current_depth); + cur.pit() = pit; + } + newpit = distance(bgn, dest); pit_type const len = distance(start, finish); pars.splice(dest, start, finish); cur.pit() = newpit - len; @@ -449,7 +542,7 @@ static void outline(OutlineOp mode, Cursor & cur) DocumentClass const & tc = buf.params().documentClass(); DocumentClass::const_iterator lit = tc.begin(); DocumentClass::const_iterator len = tc.end(); - int const newtoclevel = + int const newtoclevel = (mode == OutlineIn ? toclevel + 1 : toclevel - 1); LabelType const oldlabeltype = start->layout().labeltype; @@ -481,14 +574,14 @@ bool Text::isRTL(Paragraph const & par) const return par.isRTL(buffer.params()); } - + namespace { - + Language const * getLanguage(Cursor const & cur, string const & lang) { return lang.empty() ? cur.getFont().language() : languages.getLanguage(lang); } -} +} // namespace void Text::dispatch(Cursor & cur, FuncRequest & cmd) @@ -515,7 +608,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) cur.noScreenUpdate(); LBUFERR(this == cur.text()); - + // NOTE: This should NOT be a reference. See commit 94a5481a. CursorSlice const oldTopSlice = cur.top(); bool const oldBoundary = cur.boundary(); @@ -583,7 +676,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) if (cur.selection()) cutSelection(cur, true, false); else - deleteWordForward(cur); + deleteWordForward(cur, cmd.getArg(0) == "force"); finishChange(cur, false); break; @@ -591,7 +684,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) if (cur.selection()) cutSelection(cur, true, false); else - deleteWordBackward(cur); + deleteWordBackward(cur, cmd.getArg(0) == "force"); finishChange(cur, false); break; @@ -832,6 +925,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) break; } cur.pos() = cur.lastpos(); + cur.boundary(false); + cur.setCurrentFont(); needsUpdate |= cur != old_cur; break; @@ -1048,22 +1143,18 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_CHAR_DELETE_FORWARD: if (!cur.selection()) { - bool was_separator = cur.paragraph().isEnvSeparator(cur.pos()); if (cur.pos() == cur.paragraph().size()) // Par boundary, force full-screen update singleParUpdate = false; - needsUpdate |= erase(cur); - cur.resetAnchor(); - if (was_separator && cur.pos() == cur.paragraph().size() - && (!cur.paragraph().layout().isEnvironment() - || cur.paragraph().size() > 0)) { - // Force full-screen update - singleParUpdate = false; - needsUpdate |= erase(cur); + else if (cmd.getArg(0) != "force" && cur.confirmDeletion()) { cur.resetAnchor(); + cur.selection(true); + cur.posForward(); + cur.setSelection(); + break; } - // It is possible to make it a lot faster still - // just comment out the line below... + needsUpdate |= erase(cur); + cur.resetAnchor(); } else { cutSelection(cur, true, false); singleParUpdate = false; @@ -1079,6 +1170,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // Par boundary, full-screen update if (par_boundary) singleParUpdate = false; + else if (cmd.getArg(0) != "force" && cur.confirmDeletion(true)) { + cur.resetAnchor(); + cur.selection(true); + cur.posBackward(); + cur.setSelection(); + break; + } needsUpdate |= backspace(cur); cur.resetAnchor(); if (par_boundary && !first_par && cur.pos() > 0 @@ -1099,39 +1197,31 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) Paragraph const & par = pars_[pit]; bool lastpar = (pit == pit_type(pars_.size() - 1)); Paragraph const & nextpar = lastpar ? par : pars_[pit + 1]; - pit_type prev = pit; - if (pit > 0) { - if (!pars_[pit - 1].layout().isEnvironment()) - prev = depthHook(pit, par.getDepth()); - else if (pars_[pit - 1].getDepth() >= par.getDepth()) - prev = pit - 1; - } + pit_type prev = pit > 0 ? depthHook(pit, par.getDepth()) : pit; if (prev < pit && cur.pos() == par.beginOfBody() - && !par.isEnvSeparator(par.size() ? par.size() - 1 : 0) + && !par.size() && !par.isEnvSeparator(cur.pos()) && !par.layout().isCommand() && pars_[prev].layout() != par.layout() && pars_[prev].layout().isEnvironment() - && (!nextpar.isEnvSeparator(nextpar.size() ? nextpar.size() - 1 : 0) - || nextpar.layout().isCommand() - || nextpar.layout().isEnvironment())) { + && !nextpar.isEnvSeparator(nextpar.beginOfBody())) { if (par.layout().isEnvironment() && pars_[prev].getDepth() == par.getDepth()) { docstring const layout = par.layout().name(); DocumentClass const & tc = bv->buffer().params().documentClass(); lyx::dispatch(FuncRequest(LFUN_LAYOUT, tc.plainLayout().name())); - lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "parbreak")); + lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain")); lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse")); lyx::dispatch(FuncRequest(LFUN_LAYOUT, layout)); } else { - lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "parbreak")); + lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain")); breakParagraph(cur); } Font const f(inherit_font, cur.current_font.language()); pars_[cur.pit() - 1].resetFonts(f); } else { - if (par.isEnvSeparator(cur.pos())) + if (par.isEnvSeparator(cur.pos()) && cmd.getArg(1) != "ignoresep") cur.posForward(); - breakParagraph(cur, cmd.argument() == "inverse"); + breakParagraph(cur, cmd.getArg(0) == "inverse"); } cur.resetAnchor(); // If we have a list and autoinsert item insets, @@ -1185,6 +1275,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) if (cur.selection()) cutSelection(cur, true, false); cur.insert(inset); + cur.forceBufferUpdate(); if (inset->editable() && inset->asInsetText()) inset->edit(cur, true); else @@ -1229,6 +1320,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } ins->setParams(inspar); + break; } case LFUN_SPACE_INSERT: @@ -1245,6 +1337,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) string const name = to_utf8(cmd.argument()); if (name == "hyphenation") specialChar(cur, InsetSpecialChar::HYPHENATION); + else if (name == "allowbreak") + specialChar(cur, InsetSpecialChar::ALLOWBREAK); else if (name == "ligature-break") specialChar(cur, InsetSpecialChar::LIGATURE_BREAK); else if (name == "slash") @@ -1404,7 +1498,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) break; case LFUN_LAYOUT: { - docstring layout = cmd.argument(); + bool const ignoreautonests = cmd.getArg(1) == "ignoreautonests"; + docstring layout = ignoreautonests ? from_utf8(cmd.getArg(0)) : cmd.argument(); LYXERR(Debug::INFO, "LFUN_LAYOUT: (arg) " << to_utf8(layout)); Paragraph const & para = cur.paragraph(); @@ -1458,8 +1553,18 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } } - if (change_layout) + if (change_layout) { setLayout(cur, layout); + if (cur.pit() > 0 && !ignoreautonests) { + set const & autonests = + pars_[cur.pit() - 1].layout().autonests(); + set const & autonested = + pars_[cur.pit()].layout().isAutonestedBy(); + if (autonests.find(layout) != autonests.end() + || autonested.find(old_layout) != autonested.end()) + lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT)); + } + } Layout::LaTeXArgMap args = tclass[layout].args(); Layout::LaTeXArgMap::const_iterator lait = args.begin(); @@ -1477,36 +1582,75 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_ENVIRONMENT_SPLIT: { bool const outer = cmd.argument() == "outer"; + bool const previous = cmd.argument() == "previous"; + bool const before = cmd.argument() == "before"; + bool const normal = cmd.argument().empty(); Paragraph const & para = cur.paragraph(); - docstring layout = para.layout().name(); + docstring layout; + if (para.layout().isEnvironment()) + layout = para.layout().name(); depth_type split_depth = cur.paragraph().params().depth(); - if (outer) { - // check if we have an environment in our nesting hierarchy + depth_type nextpar_depth = 0; + if (outer || previous) { + // check if we have an environment in our scope pit_type pit = cur.pit(); Paragraph cpar = pars_[pit]; while (true) { - if (pit == 0 || cpar.params().depth() == 0) + if (pit == 0) break; --pit; cpar = pars_[pit]; + if (layout.empty() && previous + && cpar.layout().isEnvironment() + && cpar.params().depth() <= split_depth) + layout = cpar.layout().name(); if (cpar.params().depth() < split_depth && cpar.layout().isEnvironment()) { - layout = cpar.layout().name(); + if (!previous) + layout = cpar.layout().name(); split_depth = cpar.params().depth(); } + if (cpar.params().depth() == 0) + break; } } - if (cur.pos() > 0) + if ((outer || normal) && cur.pit() < cur.lastpit()) { + // save nesting of following paragraph + Paragraph cpar = pars_[cur.pit() + 1]; + nextpar_depth = cpar.params().depth(); + } + if (before) + cur.top().setPitPos(cur.pit(), 0); + if (before || cur.pos() > 0) lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK)); + else if (previous && cur.nextInset() && cur.nextInset()->lyxCode() == SEPARATOR_CODE) + lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse ignoresep")); if (outer) { while (cur.paragraph().params().depth() > split_depth) lyx::dispatch(FuncRequest(LFUN_DEPTH_DECREMENT)); } DocumentClass const & tc = bv->buffer().params().documentClass(); - lyx::dispatch(FuncRequest(LFUN_LAYOUT, tc.plainLayout().name())); + lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"") + tc.plainLayout().name() + + from_ascii("\" ignoreautonests"))); lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain")); - lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse")); + if (before) { + cur.backwardPos(); + lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse ignoresep")); + while (cur.paragraph().params().depth() < split_depth) + lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT)); + } + 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 + 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)) + lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT)); + cur.setCursor(scur); + } break; } @@ -1564,26 +1708,44 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) while (pos > 0 && par.isDeleted(pos - 1)) --pos; - BufferParams const & bufparams = bv->buffer().params(); - bool const hebrew = - par.getFontSettings(bufparams, pos).language()->lang() == "hebrew"; - bool const allow_inset_quote = !(par.isPassThru() || hebrew); - - string const arg = to_utf8(cmd.argument()); - if (allow_inset_quote) { - char_type c = ' '; - if (pos > 0 && (!cur.prevInset() || !cur.prevInset()->isSpace())) + bool const inner = (cmd.getArg(0) == "single" || cmd.getArg(0) == "inner"); + + // Guess quote side. + // A space triggers an opening quote. This is passed if the preceding + // char/inset is a space or at paragraph start. + char_type c = ' '; + if (pos > 0 && !par.isSpace(pos - 1)) { + if (cur.prevInset() && cur.prevInset()->lyxCode() == QUOTE_CODE) { + // If an opening double quotation mark precedes, and this + // is a single quote, make it opening as well + InsetQuotes & ins = + static_cast(*cur.prevInset()); + string const type = ins.getType(); + if (!suffixIs(type, "ld") || !inner) + c = par.getChar(pos - 1); + } + else if (!cur.prevInset() + || (cur.prevInset() && cur.prevInset()->isChar())) + // If a char precedes, pass that and let InsetQuote decide c = par.getChar(pos - 1); - InsetQuotes::QuoteTimes const quote_type = (arg == "single") - ? InsetQuotes::SingleQuotes : InsetQuotes::DoubleQuotes; - cur.insert(new InsetQuotes(cur.buffer(), c, quote_type)); - cur.posForward(); - } else { - // The cursor might have been invalidated by the replaceSelection. - cur.buffer()->changed(true); - string const quote_string = (arg == "single") ? "'" : "\""; - lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, quote_string)); + else { + while (pos > 0) { + if (par.getInset(pos - 1) + && !par.getInset(pos - 1)->isPartOfTextSequence()) { + // skip "invisible" insets + --pos; + continue; + } + c = par.getChar(pos - 1); + break; + } + } } + InsetQuotesParams::QuoteLevel const quote_level = inner + ? InsetQuotesParams::SecondaryQuotes : InsetQuotesParams::PrimaryQuotes; + cur.insert(new InsetQuotes(cur.buffer(), c, quote_level, cmd.getArg(1), cmd.getArg(2))); + cur.buffer()->updateBuffer(); + cur.posForward(); break; } @@ -1619,9 +1781,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) bvcur.setMark(false); switch (cmd.button()) { case mouse_button::button1: - // Set the cursor - if (!bv->mouseSetCursor(cur, cmd.argument() == "region-select")) - cur.screenUpdateFlags(Update::FitCursor); + if (!bvcur.selection()) + // Set the cursor + bvcur.resetAnchor(); + if (!bv->mouseSetCursor(cur, cmd.modifier() == ShiftModifier)) + cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor); if (bvcur.wordSelection()) selectWord(bvcur, WHOLE_WORD); break; @@ -1674,6 +1838,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) tm->setCursorFromCoordinates(cur, cmd.x(), y); cur.setTargetX(cmd.x()); + // Don't allow selecting a separator inset + if (cur.pos() && cur.paragraph().isEnvSeparator(cur.pos() - 1)) + cur.posBackward(); if (cmd.y() >= wh) lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT)); else if (cmd.y() < 0) @@ -1688,7 +1855,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); - bvcur.setSelection(true); + bvcur.selection(true); + bvcur.setCurrentFont(); if (cur.top() == old) { // We didn't move one iota, so no need to update the screen. cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor); @@ -1768,13 +1936,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } case LFUN_HREF_INSERT: { - // FIXME If we're actually given an argument, shouldn't - // we use it, whether or not we have a selection? docstring content = cmd.argument(); - if (cur.selection()) { + if (content.empty() && cur.selection()) content = cur.selectionAsString(false); - cutSelection(cur, true, false); - } InsetCommandParams p(HYPERLINK_CODE); if (!content.empty()){ @@ -1849,6 +2013,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) break; cur.recordUndo(); insertInset(cur, inset); + cur.forceBufferUpdate(); cur.posForward(); break; } @@ -2025,7 +2190,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) // don't pass "on" as argument // (it would appear literally in the first cell) docstring sel = cur.selectionAsString(false); - MathMacroTemplate * macro = new MathMacroTemplate(cur.buffer()); + InsetMathMacroTemplate * macro = new InsetMathMacroTemplate(cur.buffer()); // create a macro template if we see "\\newcommand" somewhere, and // an ordinary formula otherwise if (!sel.empty() @@ -2061,7 +2226,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) MacroType type = MacroTypeNewcommand; if (s2 == "def") type = MacroTypeDef; - MathMacroTemplate * inset = new MathMacroTemplate(cur.buffer(), + InsetMathMacroTemplate * inset = new InsetMathMacroTemplate(cur.buffer(), from_utf8(token(s, ' ', 0)), nargs, false, type); inset->setBuffer(bv->buffer()); insertInset(cur, inset); @@ -2070,7 +2235,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) cur.push(*inset); cur.top().pos() = cur.top().lastpos(); cur.resetAnchor(); - cur.setSelection(true); + cur.selection(true); cur.top().pos() = 0; } break; @@ -2149,6 +2314,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) break; } + case LFUN_FONT_CROSSOUT: { + Font font(ignore_font, ignore_language); + font.fontInfo().setXout(FONT_TOGGLE); + toggleAndShow(cur, this, font); + break; + } + case LFUN_FONT_UNDERUNDERLINE: { Font font(ignore_font, ignore_language); font.fontInfo().setUuline(FONT_TOGGLE); @@ -2446,7 +2618,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_ESCAPE: if (cur.selection()) { - cur.setSelection(false); + cur.selection(false); } else { cur.undispatched(); // This used to be LFUN_FINISHED_RIGHT, I think FORWARD is more @@ -2456,27 +2628,27 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) break; case LFUN_OUTLINE_UP: - outline(OutlineUp, cur); + outline(OutlineUp, cur, this); setCursor(cur, cur.pit(), 0); cur.forceBufferUpdate(); needsUpdate = true; break; case LFUN_OUTLINE_DOWN: - outline(OutlineDown, cur); + outline(OutlineDown, cur, this); setCursor(cur, cur.pit(), 0); cur.forceBufferUpdate(); needsUpdate = true; break; case LFUN_OUTLINE_IN: - outline(OutlineIn, cur); + outline(OutlineIn, cur, this); cur.forceBufferUpdate(); needsUpdate = true; break; case LFUN_OUTLINE_OUT: - outline(OutlineOut, cur); + outline(OutlineOut, cur, this); cur.forceBufferUpdate(); needsUpdate = true; break; @@ -2731,7 +2903,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_CAPTION_INSERT: { code = CAPTION_CODE; string arg = cmd.getArg(0); - bool varia = arg != "LongTableNoNumber" + bool varia = arg != "Unnumbered" && cur.inset().allowsCaptionVariation(arg); // not allowed in description items, // and in specific insets @@ -2815,19 +2987,13 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, for (; pit <= lastpit; ++pit) { if (pars_[pit].layout() != lay) break; - InsetList::const_iterator it = pars_[pit].insetList().begin(); - InsetList::const_iterator end = pars_[pit].insetList().end(); - for (; it != end; ++it) { - if (it->inset->lyxCode() == ARG_CODE) { - InsetArgument const * ins = - static_cast(it->inset); + for (auto const & table : pars_[pit].insetList()) + if (InsetArgument const * ins = table.inset->asInsetArgument()) if (ins->name() == arg) { // we have this already enable = false; break; } - } - } } } else enable = false; @@ -2871,6 +3037,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_QUOTE_INSERT: // always allow this, since we will inset a raw quote // if an inset is not allowed. + allow_in_passthru = true; break; case LFUN_SPECIALCHAR_INSERT: code = SPECIALCHAR_CODE; @@ -3116,10 +3283,11 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_LAYOUT: { DocumentClass const & tclass = cur.buffer()->params().documentClass(); - docstring layout = cmd.argument(); + bool const ignoreautonests = cmd.getArg(1) == "ignoreautonests"; + docstring layout = ignoreautonests ? from_utf8(cmd.getArg(0)) : cmd.argument(); if (layout.empty()) layout = tclass.defaultLayoutName(); - enable = !cur.inset().forcePlainLayout() && tclass.hasLayout(layout); + enable = !owner_->forcePlainLayout() && tclass.hasLayout(layout); flag.setOnOff(layout == cur.paragraph().layout().name()); break; @@ -3143,8 +3311,22 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, enable = res; break; } + else if (cmd.argument() == "previous") { + // look if we have an environment in the previous par + pit_type pit = cur.pit(); + Paragraph cpar = pars_[pit]; + if (pit > 0) { + --pit; + cpar = pars_[pit]; + enable = cpar.layout().isEnvironment(); + break; + } + enable = false; + break; + } else if (cur.paragraph().layout().isEnvironment()) { - enable = true; + enable = cmd.argument() == "before" + || cur.pos() > 0 || !isFirstInSequence(cur.pit()); break; } enable = false; @@ -3155,7 +3337,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_PARAGRAPH_PARAMS: case LFUN_PARAGRAPH_PARAMS_APPLY: case LFUN_PARAGRAPH_UPDATE: - enable = cur.inset().allowParagraphCustomization(); + enable = owner_->allowParagraphCustomization(); break; // FIXME: why are accent lfuns forbidden with pass_thru layouts? @@ -3185,6 +3367,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_FONT_STATE: case LFUN_FONT_UNDERLINE: case LFUN_FONT_STRIKEOUT: + case LFUN_FONT_CROSSOUT: case LFUN_FONT_UNDERUNDERLINE: case LFUN_FONT_UNDERWAVE: case LFUN_TEXTSTYLE_APPLY: