X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FText3.cpp;h=43c68ca23fbe36dc8512db86ce09edd7f335b4bd;hb=72a488d7e6b56432263c80dd92cd6acc565e03a7;hp=0467aa8b69f4fa26dac881bbd683894140d23f2c;hpb=b917c4e40f9f5cd3d101444600eddafcca54d6e3;p=lyx.git diff --git a/src/Text3.cpp b/src/Text3.cpp index 0467aa8b69..43c68ca23f 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -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); @@ -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(); @@ -583,7 +586,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 +594,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; @@ -1051,6 +1054,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) if (cur.pos() == cur.paragraph().size()) // Par boundary, force full-screen update singleParUpdate = false; + else if (cmd.getArg(0) != "force" && cur.confirmDeletion()) { + cur.resetAnchor(); + cur.selection(true); + cur.posForward(); + cur.setSelection(); + break; + } needsUpdate |= erase(cur); cur.resetAnchor(); } else { @@ -1068,6 +1078,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 @@ -1088,13 +1105,7 @@ 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.size() && !par.isEnvSeparator(cur.pos()) && !par.layout().isCommand() @@ -1551,26 +1562,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; } @@ -1606,9 +1635,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; @@ -1659,7 +1690,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) int const wh = bv->workHeight(); int const y = max(0, min(wh - 1, cmd.y())); - tm->setCursorFromCoordinates(cur, cmd.x(), y); + tm->setCursorFromCoordinates(cur, cmd.x(), y, true); cur.setTargetX(cmd.x()); // Don't allow selecting a separator inset if (cur.pos() && cur.paragraph().isEnvSeparator(cur.pos() - 1)) @@ -1758,13 +1789,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()){ @@ -2861,6 +2888,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;