From f1951c97001ea95bc22fef66ede1f771231c33d3 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Wed, 15 Jun 2016 00:09:15 +0200 Subject: tdf#100275 sw: fix target node of bookmark copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the defensive programming band-aid of 5c1a1d1c66aff497702abc20df5832fa348f1008 with a real fix. The problem is that lcl_NonCopyCount() has some special case code to ignore the first node in the target document, which erroneously is executed for every bookmark, which results in the 2 bookmarks in the bugdoc being created with nDelCount 1 and 2 so they land on the same node, which is not allowed for cross-reference marks. Extract the adjustment into a separate function that is called once. (regression from 689962feae2054f965a7378c3408b0ccfad2bbd5) (cherry picked from commit bc387975b11d87868884ec770a2a42a4f7092b5f) Change-Id: Ie14c650f7fdb259c13cb9048226da30971d2ab3c Reviewed-on: https://gerrit.libreoffice.org/26291 Tested-by: Jenkins Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- .../core/doc/DocumentContentOperationsManager.cxx | 45 ++++++++++++++-------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 7894515daa68..3c8004873ca0 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -121,6 +121,23 @@ namespace return false; } + SwNodeIndex InitDelCount(SwPaM const& rSourcePaM, sal_uLong & rDelCount) + { + SwNodeIndex const& rStart(rSourcePaM.Start()->nNode); + // Special handling for SwDoc::AppendDoc + if (rSourcePaM.GetDoc()->GetNodes().GetEndOfExtras().GetIndex() + 1 + == rStart.GetIndex()) + { + rDelCount = 1; + return SwNodeIndex(rStart, +1); + } + else + { + rDelCount = 0; + return SwNodeIndex(rStart); + } + } + /* The lcl_CopyBookmarks function has to copy bookmarks from the source to the destination nodes array. It is called after a call of the _CopyNodes(..) function. But this function does not copy @@ -132,7 +149,6 @@ namespace of "non-copy" nodes between rPam.Start() and rLastIdx. nNewIdx is the new position of interest. */ - static void lcl_NonCopyCount( const SwPaM& rPam, SwNodeIndex& rLastIdx, const sal_uLong nNewIdx, sal_uLong& rDelCount ) { sal_uLong nStart = rPam.Start()->nNode.GetIndex(); @@ -140,18 +156,14 @@ namespace if( rLastIdx.GetIndex() < nNewIdx ) // Moving forward? { // We never copy the StartOfContent node - // Special handling for SwDoc::AppendDoc - if( rPam.GetDoc()->GetNodes().GetEndOfExtras().GetIndex() + 1 == nStart ) - { - ++rDelCount; - ++rLastIdx; - } do // count "non-copy" nodes { SwNode& rNode = rLastIdx.GetNode(); if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd ) || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) ) + { ++rDelCount; + } ++rLastIdx; } while( rLastIdx.GetIndex() < nNewIdx ); @@ -164,7 +176,9 @@ namespace SwNode& rNode = rLastIdx.GetNode(); if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd ) || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) ) + { --rDelCount; + } rLastIdx--; } } @@ -232,8 +246,8 @@ namespace } } // We have to count the "non-copied" nodes.. - SwNodeIndex aCorrIdx(rStt.nNode); - sal_uLong nDelCount = 0; + sal_uLong nDelCount; + SwNodeIndex aCorrIdx(InitDelCount(rPam, nDelCount)); for(mark_vector_t::const_iterator ppMark = vMarksToCopy.begin(); ppMark != vMarksToCopy.end(); ++ppMark) @@ -253,12 +267,9 @@ namespace aTmpPam, pMark->GetName(), IDocumentMarkAccess::GetType(*pMark)); - if (pNewMark) - { - // Explicitly try to get exactly the same name as in the source - // because NavigatorReminders, DdeBookmarks etc. ignore the proposed name - pDestDoc->getIDocumentMarkAccess()->renameMark(pNewMark, pMark->GetName()); - } + // Explicitly try to get exactly the same name as in the source + // because NavigatorReminders, DdeBookmarks etc. ignore the proposed name + pDestDoc->getIDocumentMarkAccess()->renameMark(pNewMark, pMark->GetName()); // copying additional attributes for bookmarks or fieldmarks ::sw::mark::IBookmark* const pNewBookmark = @@ -309,8 +320,8 @@ namespace std::unique_ptr pDelPam; const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End(); // We have to count the "non-copied" nodes - sal_uLong nDelCount = 0; - SwNodeIndex aCorrIdx( pStt->nNode ); + sal_uLong nDelCount; + SwNodeIndex aCorrIdx(InitDelCount(rPam, nDelCount)); sal_uInt16 n = 0; pSrcDoc->getIDocumentRedlineAccess().GetRedline( *pStt, &n ); -- cgit v1.2.3