X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext.C;h=a0a3c05f83bb3ed35115edd7e21222b97ea12dc0;hb=d2574b7d8e2716d3d3aea92df6576bd01c421a6c;hp=5442eba7a76c4494d033f34cbdea22a99c03689b;hpb=7c1b0062882111b1efc06c212b07b30e90b86511;p=lyx.git diff --git a/src/text.C b/src/text.C index 5442eba7a7..a0a3c05f83 100644 --- a/src/text.C +++ b/src/text.C @@ -218,7 +218,7 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex, par.insertInset(par.size(), inset, font, change); else { lex.eatLine(); - docstring line = from_utf8(lex.getString()); + docstring line = lex.getDocString(); errorList.push_back(ErrorItem(_("Unknown Inset"), line, par.id(), 0, par.size())); } @@ -316,6 +316,10 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex, par.insertInset(par.size(), new InsetLine, font, change); } else if (token == "\\newpage") { par.insertInset(par.size(), new InsetPagebreak, font, change); + } else if (token == "\\clearpage") { + par.insertInset(par.size(), new InsetClearPage, font, change); + } else if (token == "\\cleardoublepage") { + par.insertInset(par.size(), new InsetClearDoublePage, font, change); } else if (token == "\\change_unchanged") { change = Change(Change::UNCHANGED); } else if (token == "\\change_inserted") { @@ -348,7 +352,7 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex, lex.eatLine(); errorList.push_back(ErrorItem(_("Unknown token"), bformat(_("Unknown token: %1$s %2$s\n"), from_utf8(token), - from_utf8(lex.getString())), + lex.getDocString()), par.id(), 0, par.size())); } } @@ -1070,10 +1074,6 @@ void LyXText::setHeightOfRow(BufferView const & bv, pit_type const pit, } -namespace { - -} - void LyXText::breakParagraph(LCursor & cur, bool keep_layout) { BOOST_ASSERT(this == cur.text()); @@ -1086,8 +1086,8 @@ void LyXText::breakParagraph(LCursor & cur, bool keep_layout) // this is only allowed, if the current paragraph is not empty // or caption and if it has not the keepempty flag active - if (cur.lastpos() == 0 && !cpar.allowEmpty() - && layout->labeltype != LABEL_SENSITIVE) + if (cur.lastpos() == 0 && !cpar.allowEmpty() && + layout->labeltype != LABEL_SENSITIVE) return; // a layout change may affect also the following paragraph @@ -1096,10 +1096,9 @@ void LyXText::breakParagraph(LCursor & cur, bool keep_layout) // Always break behind a space // It is better to erase the space (Dekel) if (cur.pos() != cur.lastpos() && cpar.isLineSeparator(cur.pos())) - // FIXME: change tracking (MG) cpar.eraseChar(cur.pos(), cur.buffer().params().trackChanges); - // How should the layout for the new paragraph be? + // What should the layout for the new paragraph be? int preserve_layout = 0; if (keep_layout) preserve_layout = 2; @@ -1132,7 +1131,6 @@ void LyXText::breakParagraph(LCursor & cur, bool keep_layout) } while (!pars_[next_par].empty() && pars_[next_par].isNewline(0)) - // FIXME: change tracking (MG) pars_[next_par].eraseChar(0, cur.buffer().params().trackChanges); ParIterator current_it(cur); @@ -1142,13 +1140,6 @@ void LyXText::breakParagraph(LCursor & cur, bool keep_layout) updateLabels(cur.buffer(), current_it, last_it); - // Mark "carriage return" as inserted if change tracking: - if (cur.buffer().params().trackChanges) { - // FIXME: Change tracking (MG) - cur.paragraph().setChange(cur.paragraph().size(), - Change(Change::INSERTED)); - } - // FIXME: Breaking a paragraph has nothing to do with setting a cursor. // Because of the mix between the model (the paragraph contents) and the // view (the paragraph breaking in rows, we have to do this here before @@ -1159,7 +1150,6 @@ void LyXText::breakParagraph(LCursor & cur, bool keep_layout) // A singlePar update is not enough in this case. cur.updateFlags(Update::Force); - // This check is necessary. Otherwise the new empty paragraph will // be deleted automatically. And it is more friendly for the user! if (cur.pos() != 0 || isempty) @@ -1468,34 +1458,31 @@ bool LyXText::selectWordWhenUnderCursor(LCursor & cur, word_location loc) void LyXText::acceptChange(LCursor & cur) { + // FIXME: change tracking (MG) + BOOST_ASSERT(this == cur.text()); + if (!cur.selection() && cur.lastpos() != 0) return; + // FIXME: we must handle start = end = 0 + recordUndoSelection(cur, Undo::INSERT); DocIterator it = cur.selectionBegin(); DocIterator et = cur.selectionEnd(); pit_type pit = it.pit(); - bool isDeleted = pars_[pit].isDeleted(it.pos()); for (; pit <= et.pit(); ++pit) { - pos_type left = ( pit == it.pit() ? it.pos() : 0 ); - pos_type right = - ( pit == et.pit() ? et.pos() : pars_[pit].size() + 1 ); + pos_type left = (pit == it.pit() ? it.pos() : 0); + pos_type right = (pit == et.pit() ? et.pos() : pars_[pit].size()); pars_[pit].acceptChanges(left, right); - } - if (isDeleted) { - ParagraphList & plist = paragraphs(); - if (it.pit() + 1 < et.pit()) - pars_.erase(boost::next(plist.begin(), it.pit() + 1), - boost::next(plist.begin(), et.pit())); - // Paragraph merge if appropriate: - // FIXME: change tracking (MG) - if (pars_[it.pit()].isDeleted(pars_[it.pit()].size())) { - setCursorIntern(cur, it.pit() + 1, 0); - backspacePos0(cur); - } + // merge paragraph if appropriate: + // if (right >= pars_[pit].size() && pit + 1 < et.pit() && + // pars_[pit].isDeleted(pars_[pit].size())) { + // setCursorIntern(cur, pit + 1, 0); + // backspacePos0(cur); + //} } finishUndo(); cur.clearSelection(); @@ -1505,33 +1492,31 @@ void LyXText::acceptChange(LCursor & cur) void LyXText::rejectChange(LCursor & cur) { + // FIXME: change tracking (MG) + BOOST_ASSERT(this == cur.text()); + if (!cur.selection() && cur.lastpos() != 0) return; + // FIXME: we must handle start = end = 0 + recordUndoSelection(cur, Undo::INSERT); DocIterator it = cur.selectionBegin(); DocIterator et = cur.selectionEnd(); pit_type pit = it.pit(); - bool isInserted = pars_[pit].isInserted(it.pos()); for (; pit <= et.pit(); ++pit) { - pos_type left = ( pit == it.pit() ? it.pos() : 0 ); - pos_type right = - ( pit == et.pit() ? et.pos() : pars_[pit].size() + 1 ); + pos_type left = (pit == it.pit() ? it.pos() : 0); + pos_type right = (pit == et.pit() ? et.pos() : pars_[pit].size()); pars_[pit].rejectChanges(left, right); - } - if (isInserted) { - ParagraphList & plist = paragraphs(); - if (it.pit() + 1 < et.pit()) - pars_.erase(boost::next(plist.begin(), it.pit() + 1), - boost::next(plist.begin(), et.pit())); - // Paragraph merge if appropriate: - // FIXME: change tracking (MG) - if (pars_[it.pit()].isInserted(pars_[it.pit()].size())) { - setCursorIntern(cur, it.pit() + 1, 0); - backspacePos0(cur); - } + + // merge paragraph if appropriate: + // if (right >= pars_[pit].size() && pit + 1 < et.pit() && + // pars_[pit].isInserted(pars_[pit].size())) { + // setCursorIntern(cur, pit + 1, 0); + // backspacePos0(cur); + //} } finishUndo(); cur.clearSelection(); @@ -1654,28 +1639,23 @@ bool LyXText::erase(LCursor & cur) // this is the code for a normal delete, not pasting // any paragraphs recordUndo(cur, Undo::DELETE); - // FIXME: change tracking (MG) par.eraseChar(cur.pos(), cur.buffer().params().trackChanges); if (par.isDeleted(cur.pos())) cur.forwardPosNoDescend(); needsUpdate = true; - } else if (cur.pit() != cur.lastpit()) { - if (cur.buffer().params().trackChanges - && par.isInserted(cur.pos())) { - // mark "carriage return" as deleted: - // FIXME: Change tracking (MG) + } else { + if (cur.pit() == cur.lastpit()) + return dissolveInset(cur); + + if (!par.isMergedOnEndOfParDeletion(cur.buffer().params().trackChanges)) { par.setChange(cur.pos(), Change(Change::DELETED)); cur.forwardPos(); needsUpdate = true; } else { setCursorIntern(cur, cur.pit() + 1, 0); needsUpdate = backspacePos0(cur); - // FIXME: Change tracking (MG) - if (cur.paragraph().isDeleted(cur.pos())) - cur.forwardPos(); } - } else - needsUpdate = dissolveInset(cur); + } // FIXME: Inserting characters has nothing to do with setting a cursor. // Because of the mix between the model (the paragraph contents) @@ -1726,7 +1706,7 @@ bool LyXText::backspacePos0(LCursor & cur) needsUpdate = true; } // Pasting is not allowed, if the paragraphs have different - // layout. I think it is a real bug of all other + // layouts. I think it is a real bug of all other // word processors to allow it. It confuses the user. // Correction: Pasting is always allowed with standard-layout else if (par.layout() == prevpar.layout() @@ -1745,8 +1725,6 @@ bool LyXText::backspacePos0(LCursor & cur) } - - bool LyXText::backspace(LCursor & cur) { BOOST_ASSERT(this == cur.text()); @@ -1755,21 +1733,13 @@ bool LyXText::backspace(LCursor & cur) if (cur.pit() == 0) return dissolveInset(cur); - if (cur.buffer().params().trackChanges) { - // FIXME: Change tracking (MG) - // Previous paragraph, mark "carriage return" as - // deleted: - Paragraph & par = pars_[cur.pit() - 1]; - // Take care of a just inserted para break: - // FIXME: change tracking (MG) - if (!par.isInserted(par.size())) { - // FIXME: change tracking (MG) - par.setChange(par.size(), Change(Change::DELETED)); - setCursorIntern(cur, cur.pit() - 1, par.size()); - return true; - } - } + Paragraph & prev_par = pars_[cur.pit() - 1]; + if (!prev_par.isMergedOnEndOfParDeletion(cur.buffer().params().trackChanges)) { + prev_par.setChange(prev_par.size(), Change(Change::DELETED)); + setCursorIntern(cur, cur.pit() - 1, prev_par.size()); + return true; + } // The cursor is at the beginning of a paragraph, so // the backspace will collapse two paragraphs into one. needsUpdate = backspacePos0(cur); @@ -1784,7 +1754,6 @@ bool LyXText::backspace(LCursor & cur) // without the dreaded mechanism. (JMarc) setCursorIntern(cur, cur.pit(), cur.pos() - 1, false, cur.boundary()); - // FIXME: change tracking (MG) cur.paragraph().eraseChar(cur.pos(), cur.buffer().params().trackChanges); } @@ -1825,7 +1794,6 @@ bool LyXText::dissolveInset(LCursor & cur) { spos += cur.pos(); spit += cur.pit(); Buffer & b = cur.buffer(); - // FIXME: change tracking (MG) cur.paragraph().eraseChar(cur.pos(), b.params().trackChanges); if (!plist.empty()) { if (in_ert) { @@ -1865,6 +1833,8 @@ bool LyXText::redoParagraph(BufferView & bv, pit_type const pit) Paragraph & par = pars_[pit]; Buffer const & buffer = *bv.buffer(); + bool changed = false; + // Add bibitem insets if necessary if (par.layout()->labeltype == LABEL_BIBLIO) { bool hasbibitem(false); @@ -1893,8 +1863,8 @@ bool LyXText::redoParagraph(BufferView & bv, pit_type const pit) // FIXME: We should always use getFont(), see documentation of // noFontChange() in insetbase.h. LyXFont const bufferfont = buffer.params().getFont(); - InsetList::iterator ii = par.insetlist.begin(); - InsetList::iterator iend = par.insetlist.end(); + InsetList::const_iterator ii = par.insetlist.begin(); + InsetList::const_iterator iend = par.insetlist.end(); for (; ii != iend; ++ii) { Dimension dim; int const w = maxwidth_ - leftMargin(buffer, pit, ii->pos) @@ -1903,7 +1873,7 @@ bool LyXText::redoParagraph(BufferView & bv, pit_type const pit) bufferfont : getFont(buffer, par, ii->pos); MetricsInfo mi(&bv, font, w); - ii->inset->metrics(mi, dim); + changed |= ii->inset->metrics(mi, dim); } // rebreak the paragraph @@ -1940,16 +1910,16 @@ bool LyXText::redoParagraph(BufferView & bv, pit_type const pit) dim.asc += par.rows()[0].ascent(); dim.des -= par.rows()[0].ascent(); - bool const same = dim.height() == par.dim().height(); + changed |= dim.height() != par.dim().height(); par.dim() = dim; //lyxerr << "redoParagraph: " << par.rows().size() << " rows\n"; - return !same; + return changed; } -void LyXText::metrics(MetricsInfo & mi, Dimension & dim) +bool LyXText::metrics(MetricsInfo & mi, Dimension & dim) { //BOOST_ASSERT(mi.base.textwidth); if (mi.base.textwidth) @@ -1959,10 +1929,12 @@ void LyXText::metrics(MetricsInfo & mi, Dimension & dim) // save the caller's font locally: font_ = mi.base.font; + bool changed = false; + unsigned int h = 0; unsigned int w = 0; for (pit_type pit = 0, n = paragraphs().size(); pit != n; ++pit) { - redoParagraph(*mi.base.bv, pit); + changed |= redoParagraph(*mi.base.bv, pit); Paragraph & par = paragraphs()[pit]; h += par.height(); if (w < par.width()) @@ -1973,7 +1945,9 @@ void LyXText::metrics(MetricsInfo & mi, Dimension & dim) dim.asc = pars_[0].ascent(); dim.des = h - dim.asc; + changed |= dim_ != dim; dim_ = dim; + return changed; }