X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext.C;h=93b31bbec3ec4b351bc11a0d5071bed4493525db;hb=0657a91fd08e9c31d7f9e6be26055cc5050e5f8b;hp=0e394e0da8e6f3d853ec7730fbfb8ccaec2183ae;hpb=ada361536f5fe9c5f81ecd166645acedeb02b48c;p=lyx.git diff --git a/src/text.C b/src/text.C index 0e394e0da8..93b31bbec3 100644 --- a/src/text.C +++ b/src/text.C @@ -53,6 +53,7 @@ #include "frontends/FontMetrics.h" #include "frontends/Painter.h" +#include "frontends/Selection.h" #include "insets/insettext.h" #include "insets/insetbibitem.h" @@ -828,6 +829,7 @@ void LyXText::selectWord(LCursor & cur, word_location loc) cur.resetAnchor(); setCursor(cur, to.pit(), to.pos()); cur.setSelection(); + theSelection().haveSelection(cur.selection()); } @@ -843,85 +845,111 @@ bool LyXText::selectWordWhenUnderCursor(LCursor & cur, word_location loc) } -void LyXText::acceptChange(LCursor & cur) +void LyXText::acceptOrRejectChange(LCursor & cur, bool accept) { - // 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::INSERT); - - 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()); - - // handle imaginary end-of-par character first - if (right == pars_[pit].size() && !pars_[pit].isUnchanged(right)) { - if (pars_[pit].isInserted(right)) { - pars_[pit].setChange(right, Change(Change::UNCHANGED)); - } else { - // if (pit + 1 < et.pit()) { - // setCursorIntern(cur, pit + 1, 0); - // backspacePos0(cur); - // } - } - } + recordUndoSelection(cur, Undo::ATOMIC); - pars_[pit].acceptChanges(left, right); - } - finishUndo(); - cur.clearSelection(); - setCursorIntern(cur, it.pit(), it.pos()); - cur.updateFlags(Update::Force); -} + pit_type begPit = cur.selectionBegin().pit(); + pit_type endPit = cur.selectionEnd().pit(); + pos_type begPos = cur.selectionBegin().pos(); + pos_type endPos = cur.selectionEnd().pos(); -void LyXText::rejectChange(LCursor & cur) -{ - // FIXME: change tracking (MG) + // keep selection info, because endPos becomes invalid after the first loop + bool endsBeforeEndOfPar = (endPos < pars_[endPit].size()); - BOOST_ASSERT(this == cur.text()); + // 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(); - if (!cur.selection() && cur.lastpos() != 0) - return; + // ignore empty paragraphs; otherwise, an assertion will fail for + // acceptChanges(bparams, 0, 0) or rejectChanges(bparams, 0, 0) + if (parSize == 0) + continue; - // FIXME: we must handle start = end = 0 + // do not consider first paragraph if the cursor starts at pos size() + if (pit == begPit && begPos == parSize) + continue; - recordUndoSelection(cur, Undo::INSERT); + // do not consider last paragraph if the cursor ends at pos 0 + if (pit == endPit && endPos == 0) + break; // last iteration anyway - 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()); + pos_type left = (pit == begPit ? begPos : 0); + pos_type right = (pit == endPit ? endPos : parSize); - // 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); - // } + if (accept) { + pars_[pit].acceptChanges(cur.buffer().params(), left, right); + } else { + pars_[pit].rejectChanges(cur.buffer().params(), left, right); + } + } + + // next, accept/reject imaginary end-of-par characters + + for (pit_type pit = begPit; pit <= endPit; ++pit) { + pos_type pos = pars_[pit].size(); + + // skip if the selection ends before the end-of-par + if (pit == endPit && endsBeforeEndOfPar) + break; // last iteration anyway + + // skip if this is not the last paragraph of the document + // note: the user should be able to accept/reject the par break of the last par! + if (pit == endPit && pit != pars_.size() - 1) + break; // last iteration anway + + if (accept) { + if (pars_[pit].isInserted(pos)) { + pars_[pit].setChange(pos, Change(Change::UNCHANGED)); + } else if (pars_[pit].isDeleted(pos)) { + if (pit == pars_.size() - 1) { + // 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; + --pit; + } + } + } else { + if (pars_[pit].isDeleted(pos)) { + pars_[pit].setChange(pos, Change(Change::UNCHANGED)); + } else if (pars_[pit].isInserted(pos)) { + if (pit == pars_.size() - 1) { + // we mark the par break at the end of the last paragraph unchanged + pars_[pit].setChange(pos, Change(Change::UNCHANGED)); + } else { + mergeParagraph(cur.buffer().params(), pars_, pit); + --endPit; + --pit; + } } } - - 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 >= begPit; --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, begPit, begPos); cur.updateFlags(Update::Force); + updateLabels(cur.buffer()); } @@ -1040,9 +1068,10 @@ bool LyXText::erase(LCursor & cur) // this is the code for a normal delete, not pasting // any paragraphs recordUndo(cur, Undo::DELETE); - par.eraseChar(cur.pos(), cur.buffer().params().trackChanges); - if (par.isDeleted(cur.pos())) + if(!par.eraseChar(cur.pos(), cur.buffer().params().trackChanges)) { + // the character has been logically deleted only => skip it cur.forwardPosNoDescend(); + } needsUpdate = true; } else { if (cur.pit() == cur.lastpit()) @@ -1560,7 +1589,7 @@ docstring LyXText::currentState(LCursor & cur) odocstringstream os; if (buf.params().trackChanges) - os << "[C] "; + os << _("[Change Tracking] "); Change change = par.lookupChange(cur.pos()); @@ -1722,6 +1751,8 @@ void LyXText::setCursorFromCoordinates(LCursor & cur, int const x, int const y) << endl; setCursor(cur, pit, pos, true, bound); + // remember new position. + cur.setTargetX(); }