From a948d133331ca32052b686bf935f2ef61451220d Mon Sep 17 00:00:00 2001 From: Vincent van Ravesteijn Date: Tue, 1 Jun 2010 16:13:54 +0000 Subject: [PATCH] Fix bug #6744: Crash when copying an inset from a deleted section. We need to reject the changes in when copying from a fully deleted section. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@34583 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/CutAndPaste.cpp | 2 ++ src/Text.cpp | 54 +++++++++++++++++++++++++++++++-------------- src/Text.h | 3 +++ 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp index 4cc10d59f4..07274a39a0 100644 --- a/src/CutAndPaste.cpp +++ b/src/CutAndPaste.cpp @@ -539,6 +539,8 @@ void copySelectionHelper(Buffer const & buf, Text const & text, // deleted, unless the whole selection was deleted if (!isFullyDeleted(copy_pars)) acceptChanges(copy_pars, buf.params()); + else + rejectChanges(copy_pars, buf.params()); // do some final cleanup now, to make sure that the paragraphs diff --git a/src/Text.cpp b/src/Text.cpp index 6cc354dfd7..8f106b42c6 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -259,37 +259,59 @@ Font const Text::outerFont(pit_type par_offset) const } -void acceptChanges(ParagraphList & pars, BufferParams const & bparams) +static void acceptOrRejectChanges(ParagraphList & pars, + BufferParams const & bparams, Text::ChangeOp op) { pit_type pars_size = static_cast(pars.size()); - // first, accept changes within each individual paragraph - // (do not consider end-of-par) + // first, accept or reject changes within each individual + // paragraph (do not consider end-of-par) for (pit_type pit = 0; pit < pars_size; ++pit) { - if (!pars[pit].empty()) // prevent assertion failure - pars[pit].acceptChanges(0, pars[pit].size()); + // prevent assertion failure + if (!pars[pit].empty()) { + if (op == Text::ACCEPT) + pars[pit].acceptChanges(0, pars[pit].size()); + else + pars[pit].rejectChanges(0, pars[pit].size()); + } } - // next, accept imaginary end-of-par characters + // next, accept or reject imaginary end-of-par characters for (pit_type pit = 0; pit < pars_size; ++pit) { pos_type pos = pars[pit].size(); - - 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 + if (pars[pit].isChanged(pos)) { + // keep the end-of-par char if it is inserted and accepted + // or when it is deleted and rejected. + if (pars[pit].isInserted(pos) == (op == Text::ACCEPT)) { pars[pit].setChange(pos, Change(Change::UNCHANGED)); } else { - mergeParagraph(bparams, pars, pit); - --pit; - --pars_size; + 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(bparams, pars, pit); + --pit; + --pars_size; + } } } } } + +void acceptChanges(ParagraphList & pars, BufferParams const & bparams) +{ + acceptOrRejectChanges(pars, bparams, Text::ACCEPT); +} + + +void rejectChanges(ParagraphList & pars, BufferParams const & bparams) +{ + acceptOrRejectChanges(pars, bparams, Text::REJECT); +} + + InsetText const & Text::inset() const { return *owner_; diff --git a/src/Text.h b/src/Text.h index e6826e2893..e3421e2e5f 100644 --- a/src/Text.h +++ b/src/Text.h @@ -395,6 +395,9 @@ void mergeParagraph(BufferParams const & bparams, /// accept the changes within the complete ParagraphList void acceptChanges(ParagraphList & pars, BufferParams const & bparams); +/// reject the changes within the complete ParagraphList +void rejectChanges(ParagraphList & pars, BufferParams const & bparams); + } // namespace lyx #endif // TEXT_H -- 2.39.2