X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FText.cpp;h=1eecee1e30443e9b068a24538508a361de7fac97;hb=948ed1ffd50923f3e63204c65a08cb308ebc4b63;hp=589fd25d83150d3275006e9ecb74927679841836;hpb=8b00b355ca7012ca703c78a8be89193ac6435fcb;p=lyx.git diff --git a/src/Text.cpp b/src/Text.cpp index 589fd25d83..1eecee1e30 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -157,7 +157,7 @@ void breakParagraphConservative(BufferParams const & bparams, } // Move over the end-of-par change information tmp.setChange(tmp.size(), par.lookupChange(par.size())); - par.setChange(par.size(), Change(bparams.trackChanges ? + par.setChange(par.size(), Change(bparams.track_changes ? Change::INSERTED : Change::UNCHANGED)); } } @@ -198,7 +198,7 @@ void mergeParagraph(BufferParams const & bparams, Text::Text(InsetText * owner, bool use_default_layout) - : owner_(owner), autoBreakRows_(false), undo_counter_(0) + : owner_(owner) { pars_.push_back(Paragraph()); Paragraph & par = pars_.back(); @@ -212,7 +212,7 @@ Text::Text(InsetText * owner, bool use_default_layout) Text::Text(InsetText * owner, Text const & text) - : owner_(owner), autoBreakRows_(text.autoBreakRows_), undo_counter_(0) + : owner_(owner) { pars_ = text.pars_; ParagraphList::iterator const end = pars_.end(); @@ -486,18 +486,42 @@ void Text::readParToken(Paragraph & par, Lexer & lex, } else if (token == "\\color") { lex.next(); setLyXColor(lex.getString(), font.fontInfo()); - } else if (token == "\\SpecialChar") { + } else if (token == "\\SpecialChar" || + (token == "\\SpecialCharNoPassThru" && + !par.layout().pass_thru && !inset().isPassThru())) { auto_ptr inset; inset.reset(new InsetSpecialChar); inset->read(lex); inset->setBuffer(*buf); par.insertInset(par.size(), inset.release(), font, change); + } else if (token == "\\SpecialCharNoPassThru") { + lex.next(); + docstring const s = ltrim(lex.getDocString(), "\\"); + par.insert(par.size(), s, font, change); } else if (token == "\\IPAChar") { auto_ptr inset; inset.reset(new InsetIPAChar); inset->read(lex); inset->setBuffer(*buf); par.insertInset(par.size(), inset.release(), font, change); + } else if (token == "\\twohyphens" || token == "\\threehyphens") { + // Ideally, this should be done by lyx2lyx, but lyx2lyx does not know the + // running font and does not know anything about layouts (and CopyStyle). + Layout const & layout(par.layout()); + FontInfo info = font.fontInfo(); + info.realize(layout.resfont); + if (layout.pass_thru || inset().isPassThru() || + info.family() == TYPEWRITER_FAMILY) { + if (token == "\\twohyphens") + par.insert(par.size(), from_ascii("--"), font, change); + else + par.insert(par.size(), from_ascii("---"), font, change); + } else { + if (token == "\\twohyphens") + par.insertChar(par.size(), 0x2013, font, change); + else + par.insertChar(par.size(), 0x2014, font, change); + } } else if (token == "\\backslash") { par.appendChar('\\', font, change); } else if (token == "\\LyXTable") { @@ -691,7 +715,7 @@ static void breakParagraph(Text & text, pit_type par_offset, pos_type pos, // Move over the end-of-par change information tmp->setChange(tmp->size(), par.lookupChange(par.size())); - par.setChange(par.size(), Change(bparams.trackChanges ? + par.setChange(par.size(), Change(bparams.track_changes ? Change::INSERTED : Change::UNCHANGED)); if (pos) { @@ -749,7 +773,7 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic) // Always break behind a space // It is better to erase the space (Dekel) if (cur.pos() != cur.lastpos() && cpar.isLineSeparator(cur.pos())) - cpar.eraseChar(cur.pos(), cur.buffer()->params().trackChanges); + cpar.eraseChar(cur.pos(), cur.buffer()->params().track_changes); // What should the layout for the new paragraph be? bool keep_layout = layout.isEnvironment() @@ -784,7 +808,7 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic) } while (!pars_[next_par].empty() && pars_[next_par].isNewline(0)) { - if (!pars_[next_par].eraseChar(0, cur.buffer()->params().trackChanges)) + if (!pars_[next_par].eraseChar(0, cur.buffer()->params().track_changes)) break; // the character couldn't be deleted physically due to change tracking } @@ -815,7 +839,7 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str, cit != str.end(); ++cit) { Paragraph & par = pars_[pit]; if (*cit == '\n') { - if (autoBreakRows_ && (!par.empty() || par.allowEmpty())) { + if (inset().allowMultiPar() && (!par.empty() || par.allowEmpty())) { lyx::breakParagraph(*this, pit, pos, par.layout().isEnvironment()); ++pit; @@ -831,11 +855,11 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str, } else if (*cit == '\t') { if (!par.isFreeSpacing()) { // tabs are like spaces here - par.insertChar(pos, ' ', font, bparams.trackChanges); + par.insertChar(pos, ' ', font, bparams.track_changes); ++pos; space_inserted = true; } else { - par.insertChar(pos, *cit, font, bparams.trackChanges); + par.insertChar(pos, *cit, font, bparams.track_changes); ++pos; space_inserted = true; } @@ -844,7 +868,7 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str, continue; } else { // just insert the character - par.insertChar(pos, *cit, font, bparams.trackChanges); + par.insertChar(pos, *cit, font, bparams.track_changes); ++pos; space_inserted = (*cit == ' '); } @@ -921,6 +945,7 @@ void Text::insertChar(Cursor & cur, char_type c) if (contains(number_unary_operators, c) && (cur.pos() == 1 || par.isSeparator(cur.pos() - 2) + || par.isEnvSeparator(cur.pos() - 2) || par.isNewline(cur.pos() - 2)) ) { setCharFont(pit, cur.pos() - 1, cur.current_font, @@ -1007,7 +1032,10 @@ void Text::insertChar(Cursor & cur, char_type c) // Prevent to insert uncodable characters in verbatim and ERT // (workaround for bug 9012) - if (cur.paragraph().isPassThru() && cur.current_font.language()) { + // 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.")); @@ -1015,14 +1043,36 @@ void Text::insertChar(Cursor & cur, char_type c) } } - par.insertChar(cur.pos(), c, cur.current_font, - cur.buffer()->params().trackChanges); + pos_type pos = cur.pos(); + if (!cur.paragraph().isPassThru() && owner_->lyxCode() != IPA_CODE && + cur.current_font.fontInfo().family() != TYPEWRITER_FAMILY && + c == '-' && pos > 0) { + if (par.getChar(pos - 1) == '-') { + // convert "--" to endash + par.eraseChar(pos - 1, cur.buffer()->params().track_changes); + c = 0x2013; + pos--; + } else if (par.getChar(pos - 1) == 0x2013) { + // convert "---" to emdash + par.eraseChar(pos - 1, cur.buffer()->params().track_changes); + c = 0x2014; + pos--; + } else if (par.getChar(pos - 1) == 0x2014) { + // convert "----" to "-" + par.eraseChar(pos - 1, cur.buffer()->params().track_changes); + c = '-'; + pos--; + } + } + + par.insertChar(pos, c, cur.current_font, + cur.buffer()->params().track_changes); cur.checkBufferStructure(); // cur.screenUpdateFlags(Update::Force); bool boundary = cur.boundary() - || tm.isRTLBoundary(cur.pit(), cur.pos() + 1); - setCursor(cur, cur.pit(), cur.pos() + 1, false, boundary); + || tm.isRTLBoundary(cur.pit(), pos + 1); + setCursor(cur, cur.pit(), pos + 1, false, boundary); charInserted(cur); } @@ -1031,15 +1081,6 @@ void Text::charInserted(Cursor & cur) { Paragraph & par = cur.paragraph(); - // Here we call finishUndo for every 20 characters inserted. - // This is from my experience how emacs does it. (Lgb) - if (undo_counter_ < 20) { - ++undo_counter_; - } else { - cur.finishUndo(); - undo_counter_ = 0; - } - // register word if a non-letter was entered if (cur.pos() > 1 && !par.isWordSeparator(cur.pos() - 2) @@ -1272,8 +1313,7 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op) LBUFERR(this == cur.text()); if (!cur.selection()) { - bool const changed = cur.paragraph().isChanged(cur.pos()); - if (!(changed && findNextChange(&cur.bv()))) + if (!selectChange(cur)) return; } @@ -1289,7 +1329,6 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op) bool endsBeforeEndOfPar = (endPos < pars_[endPit].size()); // first, accept/reject changes within each individual paragraph (do not consider end-of-par) - for (pit_type pit = begPit; pit <= endPit; ++pit) { pos_type parSize = pars_[pit].size(); @@ -1365,10 +1404,7 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op) } // finally, invoke the DEPM - - deleteEmptyParagraphMechanism(begPit, endPit, cur.buffer()->params().trackChanges); - - // + deleteEmptyParagraphMechanism(begPit, endPit, cur.buffer()->params().track_changes); cur.finishUndo(); cur.clearSelection(); @@ -1382,7 +1418,7 @@ void Text::acceptChanges() { BufferParams const & bparams = owner_->buffer().params(); lyx::acceptChanges(pars_, bparams); - deleteEmptyParagraphMechanism(0, pars_.size() - 1, bparams.trackChanges); + deleteEmptyParagraphMechanism(0, pars_.size() - 1, bparams.track_changes); } @@ -1418,7 +1454,7 @@ void Text::rejectChanges() } // finally, invoke the DEPM - deleteEmptyParagraphMechanism(0, pars_size - 1, bparams.trackChanges); + deleteEmptyParagraphMechanism(0, pars_size - 1, bparams.track_changes); } @@ -1522,7 +1558,7 @@ bool Text::handleBibitems(Cursor & cur) // if a bibitem is deleted, merge with previous paragraph // if this is a bibliography item as well if (cur.pit() > 0 && par.layout() == prevpar.layout()) { - cur.recordUndo(ATOMIC_UNDO, prevcur.pit()); + cur.recordUndo(prevcur.pit()); mergeParagraph(bufparams, cur.text()->paragraphs(), prevcur.pit()); cur.forceBufferUpdate(); @@ -1548,7 +1584,7 @@ bool Text::erase(Cursor & cur) // any paragraphs cur.recordUndo(DELETE_UNDO); bool const was_inset = cur.paragraph().isInset(cur.pos()); - if(!par.eraseChar(cur.pos(), cur.buffer()->params().trackChanges)) + if(!par.eraseChar(cur.pos(), cur.buffer()->params().track_changes)) // the character has been logically deleted only => skip it cur.top().forwardPos(); @@ -1561,7 +1597,7 @@ bool Text::erase(Cursor & cur) if (cur.pit() == cur.lastpit()) return dissolveInset(cur); - if (!par.isMergedOnEndOfParDeletion(cur.buffer()->params().trackChanges)) { + if (!par.isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) { par.setChange(cur.pos(), Change(Change::DELETED)); cur.forwardPos(); needsUpdate = true; @@ -1604,14 +1640,14 @@ bool Text::backspacePos0(Cursor & cur) // is it an empty paragraph? if (cur.lastpos() == 0 || (cur.lastpos() == 1 && par.isSeparator(0))) { - cur.recordUndo(ATOMIC_UNDO, prevcur.pit(), cur.pit()); + cur.recordUndo(prevcur.pit()); plist.erase(boost::next(plist.begin(), cur.pit())); needsUpdate = true; } // is previous par empty? else if (prevcur.lastpos() == 0 || (prevcur.lastpos() == 1 && prevpar.isSeparator(0))) { - cur.recordUndo(ATOMIC_UNDO, prevcur.pit(), cur.pit()); + cur.recordUndo(prevcur.pit()); plist.erase(boost::next(plist.begin(), prevcur.pit())); needsUpdate = true; } @@ -1623,7 +1659,7 @@ bool Text::backspacePos0(Cursor & cur) else if (par.layout() == prevpar.layout() || tclass.isDefaultLayout(par.layout()) || tclass.isPlainLayout(par.layout())) { - cur.recordUndo(ATOMIC_UNDO, prevcur.pit()); + cur.recordUndo(prevcur.pit()); mergeParagraph(bufparams, plist, prevcur.pit()); needsUpdate = true; } @@ -1648,8 +1684,8 @@ bool Text::backspace(Cursor & cur) Cursor prev_cur = cur; --prev_cur.pit(); - if (!prev_cur.paragraph().isMergedOnEndOfParDeletion(cur.buffer()->params().trackChanges)) { - cur.recordUndo(ATOMIC_UNDO, prev_cur.pit(), prev_cur.pit()); + if (!prev_cur.paragraph().isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) { + cur.recordUndo(prev_cur.pit(), prev_cur.pit()); prev_cur.paragraph().setChange(prev_cur.lastpos(), Change(Change::DELETED)); setCursorIntern(cur, prev_cur.pit(), prev_cur.lastpos()); return true; @@ -1669,7 +1705,7 @@ bool Text::backspace(Cursor & cur) setCursorIntern(cur, cur.pit(), cur.pos() - 1, false, cur.boundary()); bool const was_inset = cur.paragraph().isInset(cur.pos()); - cur.paragraph().eraseChar(cur.pos(), cur.buffer()->params().trackChanges); + cur.paragraph().eraseChar(cur.pos(), cur.buffer()->params().track_changes); if (was_inset) cur.forceBufferUpdate(); else @@ -1711,7 +1747,7 @@ bool Text::dissolveInset(Cursor & cur) spos += cur.pos(); spit += cur.pit(); Buffer & b = *cur.buffer(); - cur.paragraph().eraseChar(cur.pos(), b.params().trackChanges); + cur.paragraph().eraseChar(cur.pos(), b.params().track_changes); if (!plist.empty()) { // see bug 7319 @@ -1846,7 +1882,7 @@ docstring Text::currentState(Cursor const & cur) const Paragraph const & par = cur.paragraph(); odocstringstream os; - if (buf.params().trackChanges) + if (buf.params().track_changes) os << _("[Change Tracking] "); Change change = par.lookupChange(cur.pos()); @@ -2067,7 +2103,7 @@ void Text::charsTranspose(Cursor & cur) // And finally, we are ready to perform the transposition. // Track the changes if Change Tracking is enabled. - bool const trackChanges = cur.buffer()->params().trackChanges; + bool const trackChanges = cur.buffer()->params().track_changes; cur.recordUndo();