From 76ad6628fdbe0677628dc1304f38acffad1f1cfb Mon Sep 17 00:00:00 2001 From: Michael Schmitt Date: Tue, 23 Jan 2007 13:25:50 +0000 Subject: [PATCH] * src/text.C: implement rejectChange() as the inverse of acceptChange() (requires some further testing) git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16825 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/text.C | 92 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/src/text.C b/src/text.C index 69b16de864..fef9e5035d 100644 --- a/src/text.C +++ b/src/text.C @@ -934,42 +934,88 @@ 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) + if (!cur.selection()) return; - // FIXME: we must handle start = end = 0 + recordUndoSelection(cur, Undo::ATOMIC); - recordUndoSelection(cur, Undo::INSERT); + DocIterator beg = cur.selectionBegin(); + DocIterator end = cur.selectionEnd(); + + // first, accept changes within each individual paragraph (do not consider end-of-par) + + for (pit_type pit = beg.pit(); pit <= end.pit(); ++pit) { + // ignore empty paragraphs; otherwise, an assertion will fail for acceptChanges(0, 0) + if (pars_[pit].size() == 0) + continue; - DocIterator it = cur.selectionBegin(); - DocIterator et = cur.selectionEnd(); - pit_type pit = it.pit(); - 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()); + // do not consider first paragraph if the cursor starts at pos size() + if (pit == beg.pit() && beg.pos() == pars_[pit].size()) + continue; - // handle imaginary end-of-par character first - if (right == pars_[pit].size() && !pars_[pit].isUnchanged(right)) { - if (pars_[pit].isDeleted(right)) { - pars_[pit].setChange(right, Change(Change::UNCHANGED)); - } else { - // if (pit + 1 < et.pit()) { - // setCursorIntern(cur, pit + 1, 0); - // backspacePos0(cur); - // } + // do not consider last paragraph if the cursor ends at pos 0 + if (pit == end.pit() && end.pos() == 0) + break; // last iteration anyway + + pos_type left = (pit == beg.pit() ? beg.pos() : 0); + pos_type right = (pit == end.pit() ? end.pos() : pars_[pit].size()); + pars_[pit].rejectChanges(left, right); + } + + // next, accept imaginary end-of-par characters + // iterate from last to first paragraph such that we don't have to care for a changing 'end' + + pos_type endpit = end.pit(); + for (pit_type pit = endpit; pit >= beg.pit(); --pit) { + pos_type pos = pars_[pit].size(); + + // last paragraph of the selection requires special handling + if (pit == end.pit()) { + // skip if the selection ends before the end-of-par + if (end.pos() < pos) + continue; + + // skip if the selection ends with the end-of-par and this is not the + // last paragraph of the document + // note: the user must be able to accept the end-of-par of the last par! + if (end.pos() == pos && pit != pars_.size() - 1) + continue; + } + + + if (!pars_[pit].isUnchanged(pos)) { + if (pars_[pit].isDeleted(pos)) { + pars_[pit].setChange(pos, Change(Change::UNCHANGED)); + } else { // isInserted + if (pit == pars_.size()) { + // we cannot remove a par break at the end of the last paragraph + // instead, we mark it unchanged + pars_[pit].setChange(pos, Change(Change::UNCHANGED)); + } else { + mergeParagraph(cur.buffer().params(), pars_, pit); + endpit--; + } } } - - pars_[pit].rejectChanges(left, right); } + + // finally, invoke the DEPM + // FIXME: the following code will be changed in the near future + setCursorIntern(cur, endpit, 0); + for (pit_type pit = endpit - 1; pit >= beg.pit(); --pit) { + bool dummy; + LCursor old = cur; + setCursorIntern(cur, pit, 0); + deleteEmptyParagraphMechanism(cur, old, dummy); + } + finishUndo(); cur.clearSelection(); - setCursorIntern(cur, it.pit(), it.pos()); + setCursorIntern(cur, beg.pit(), beg.pos()); cur.updateFlags(Update::Force); + updateLabels(cur.buffer()); } -- 2.39.5