X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FText.cpp;h=e1c37faf3ab2700376d70f2d2f2e0ca2b4e3fc8a;hb=3561caa3a171a5984ee7a10b7ea82f7f4b7226e8;hp=cc404b2f1f56ac780073679b65b2b3cd407a298e;hpb=3c329db0a50689ee2384db1ae02a98aca3bf0bac;p=lyx.git diff --git a/src/Text.cpp b/src/Text.cpp index cc404b2f1f..e1c37faf3a 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -464,6 +464,9 @@ void Text::readParToken(Paragraph & par, Lexer & lex, } else if (token == "\\strikeout") { lex.next(); font.fontInfo().setStrikeout(setLyXMisc(lex.getString())); + } else if (token == "\\xout") { + lex.next(); + font.fontInfo().setXout(setLyXMisc(lex.getString())); } else if (token == "\\uuline") { lex.next(); font.fontInfo().setUuline(setLyXMisc(lex.getString())); @@ -905,12 +908,58 @@ void Text::insertStringAsParagraphs(Cursor & cur, docstring const & str, } +namespace { + +bool canInsertChar(Cursor const & cur, char_type c) +{ + Paragraph const & par = cur.paragraph(); + // If not in free spacing mode, check if there will be two blanks together or a blank at + // the beginning of a paragraph. + if (!par.isFreeSpacing() && isLineSeparatorChar(c)) { + if (cur.pos() == 0) { + cur.message(_( + "You cannot insert a space at the " + "beginning of a paragraph. Please read the Tutorial.")); + return false; + } + // LASSERT: Is it safe to continue here? + LASSERT(cur.pos() > 0, /**/); + if ((par.isLineSeparator(cur.pos() - 1) || par.isNewline(cur.pos() - 1)) + && !par.isDeleted(cur.pos() - 1)) { + cur.message(_( + "You cannot type two spaces this way. " + "Please read the Tutorial.")); + return false; + } + } + + // Prevent to insert uncodable characters in verbatim and ERT + // (workaround for bug 9012) + // Don't do it for listings inset, since InsetListings::latex() tries + // to switch to a usable encoding which works in many cases (bug 9102). + if (par.isPassThru() && cur.inset().lyxCode() != LISTINGS_CODE && + cur.current_font.language()) { + Encoding const * e = cur.current_font.language()->encoding(); + if (!e->encodable(c)) { + cur.message(_("Character is uncodable in verbatim paragraphs.")); + return false; + } + } + return true; +} + +} // namespace + + // insert a character, moves all the following breaks in the // same Paragraph one to the right and make a rebreak void Text::insertChar(Cursor & cur, char_type c) { LBUFERR(this == cur.text()); + if (!canInsertChar(cur,c)) + return; + cur.recordUndo(INSERT_UNDO); TextMetrics const & tm = cur.bv().textMetrics(this); @@ -919,9 +968,6 @@ void Text::insertChar(Cursor & cur, char_type c) // try to remove this pit_type const pit = cur.pit(); - bool const freeSpacing = par.layout().free_spacing || - par.isFreeSpacing(); - if (lyxrc.auto_number) { static docstring const number_operators = from_ascii("+-/*"); static docstring const number_unary_operators = from_ascii("+-"); @@ -1004,45 +1050,6 @@ void Text::insertChar(Cursor & cur, char_type c) } } - // Next check, if there will be two blanks together or a blank at - // the beginning of a paragraph. - // I decided to handle blanks like normal characters, the main - // difference are the special checks when calculating the row.fill - // (blank does not count at the end of a row) and the check here - - // When the free-spacing option is set for the current layout, - // disable the double-space checking - if (!freeSpacing && isLineSeparatorChar(c)) { - if (cur.pos() == 0) { - cur.message(_( - "You cannot insert a space at the " - "beginning of a paragraph. Please read the Tutorial.")); - return; - } - // LASSERT: Is it safe to continue here? - LASSERT(cur.pos() > 0, /**/); - if ((par.isLineSeparator(cur.pos() - 1) || par.isNewline(cur.pos() - 1)) - && !par.isDeleted(cur.pos() - 1)) { - cur.message(_( - "You cannot type two spaces this way. " - "Please read the Tutorial.")); - return; - } - } - - // Prevent to insert uncodable characters in verbatim and ERT - // (workaround for bug 9012) - // Don't do it for listings inset, since InsetListings::latex() tries - // to switch to a usable encoding which works in many cases (bug 9102). - if (cur.paragraph().isPassThru() && owner_->lyxCode() != LISTINGS_CODE && - cur.current_font.language()) { - Encoding const * e = cur.current_font.language()->encoding(); - if (!e->encodable(c)) { - cur.message(_("Character is uncodable in verbatim paragraphs.")); - return; - } - } - pos_type pos = cur.pos(); if (!cur.paragraph().isPassThru() && owner_->lyxCode() != IPA_CODE && cur.real_current_font.fontInfo().family() != TYPEWRITER_FAMILY && @@ -1742,20 +1749,24 @@ bool Text::dissolveInset(Cursor & cur) cur.recordUndoInset(); cur.setMark(false); cur.selHandle(false); - // save position + // save position inside inset pos_type spos = cur.pos(); pit_type spit = cur.pit(); ParagraphList plist; if (cur.lastpit() != 0 || cur.lastpos() != 0) plist = paragraphs(); cur.popBackward(); - // store cursor offset + // update cursor offset if (spit == 0) spos += cur.pos(); spit += cur.pit(); - Buffer & b = *cur.buffer(); - cur.paragraph().eraseChar(cur.pos(), b.params().track_changes); + // remember position outside inset to delete inset later + // we do not do it now to avoid memory reuse issues (see #10667). + DocIterator inset_it = cur; + // jump over inset + ++cur.pos(); + Buffer & b = *cur.buffer(); if (!plist.empty()) { // see bug 7319 // we clear the cache so that we won't get conflicts with labels @@ -1776,17 +1787,20 @@ bool Text::dissolveInset(Cursor & cur) pasteParagraphList(cur, plist, b.params().documentClassPtr(), b.errorList("Paste")); - // restore position - cur.pit() = min(cur.lastpit(), spit); - cur.pos() = min(cur.lastpos(), spos); } - cur.forceBufferUpdate(); + // delete the inset now + inset_it.paragraph().eraseChar(inset_it.pos(), b.params().track_changes); + // restore position + cur.pit() = min(cur.lastpit(), spit); + cur.pos() = min(cur.lastpos(), spos); // Ensure the current language is set correctly (bug 6292) cur.text()->setCursor(cur, cur.pit(), cur.pos()); cur.clearSelection(); cur.resetAnchor(); + cur.forceBufferUpdate(); + return true; } @@ -1882,7 +1896,7 @@ bool Text::read(Lexer & lex, // Returns the current font and depth as a message. -docstring Text::currentState(Cursor const & cur) const +docstring Text::currentState(Cursor const & cur, bool devel_mode) const { LBUFERR(this == cur.text()); Buffer & buf = *cur.buffer(); @@ -1939,22 +1953,22 @@ docstring Text::currentState(Cursor const & cur) const } } -#ifdef DEVEL_VERSION - os << _(", Inset: ") << &cur.inset(); - os << _(", Paragraph: ") << cur.pit(); - os << _(", Id: ") << par.id(); - os << _(", Position: ") << cur.pos(); - // FIXME: Why is the check for par.size() needed? - // We are called with cur.pos() == par.size() quite often. - if (!par.empty() && cur.pos() < par.size()) { - // Force output of code point, not character - size_t const c = par.getChar(cur.pos()); - os << _(", Char: 0x") << hex << c; - } - os << _(", Boundary: ") << cur.boundary(); -// Row & row = cur.textRow(); -// os << bformat(_(", Row b:%1$d e:%2$d"), row.pos(), row.endpos()); -#endif + if (devel_mode) { + os << _(", Inset: ") << &cur.inset(); + os << _(", Paragraph: ") << cur.pit(); + os << _(", Id: ") << par.id(); + os << _(", Position: ") << cur.pos(); + // FIXME: Why is the check for par.size() needed? + // We are called with cur.pos() == par.size() quite often. + if (!par.empty() && cur.pos() < par.size()) { + // Force output of code point, not character + size_t const c = par.getChar(cur.pos()); + os << _(", Char: 0x") << hex << c; + } + os << _(", Boundary: ") << cur.boundary(); +// Row & row = cur.textRow(); +// os << bformat(_(", Row b:%1$d e:%2$d"), row.pos(), row.endpos()); + } return os.str(); }