diff options
author | Michael Stahl <mstahl@redhat.com> | 2015-10-02 15:13:18 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2015-10-02 15:26:45 +0200 |
commit | c95ba3ef2613e9d5abd2f19ab2432c7bc1a40fe7 (patch) | |
tree | ccdf7efa38ab1a347e77bcc8bdb5ec97d901f26c /sw/source | |
parent | b80be50268f534e215d36d69b93d3f51d9410ace (diff) |
sw: fix copying of bookmarks in CopyRange
If the copied range starts with a not fully selected paragraph, the
bookmarks that are copied will be created on the wrong paragraphs,
on the node after the correct one.
This also happens when hinding the redlines, and causes asserts from
attempting to create CrossRefBookmarks on table nodes on WW8 export of
fdo66302-1.odt and fdo66312-1.odt.
Change-Id: Id576be3e38a89527d967f02b39d9aabbf6368354
Diffstat (limited to 'sw/source')
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 43 | ||||
-rw-r--r-- | sw/source/core/inc/DocumentContentOperationsManager.hxx | 2 |
2 files changed, 37 insertions, 8 deletions
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index ba8ea11d5b7f..36e5b51d6749 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -3131,11 +3131,14 @@ void DocumentContentOperationsManager::CopyWithFlyInFly( const SwNodeRange& rRg, const sal_Int32 nEndContentIndex, const SwNodeIndex& rInsPos, - const SwPaM* pCopiedPaM, + const std::pair<const SwPaM&, const SwPosition&>* pCopiedPaM /*and real insert pos*/, const bool bMakeNewFrms, const bool bDelRedlines, const bool bCopyFlyAtFly ) const { + assert(!pCopiedPaM || pCopiedPaM->first.End()->nContent == nEndContentIndex); + assert(!pCopiedPaM || pCopiedPaM->first.End()->nNode == rRg.aEnd); + SwDoc* pDest = rInsPos.GetNode().GetDoc(); _SaveRedlEndPosForRestore aRedlRest( rInsPos, 0 ); @@ -3178,14 +3181,24 @@ void DocumentContentOperationsManager::CopyWithFlyInFly( SwNodeRange aCpyRange( aSavePos, rInsPos ); // Also copy all bookmarks + // guess this must be done before the _DelDummyNodes below as that + // deletes nodes so would mess up the index arithmetic if( m_rDoc.getIDocumentMarkAccess()->getAllMarksCount() ) { SwPaM aRgTmp( rRg.aStart, rRg.aEnd ); - SwPaM aCpyTmp( aCpyRange.aStart, aCpyRange.aEnd ); + SwPaM aCpyPaM(aCpyRange.aStart, aCpyRange.aEnd); + if (pCopiedPaM && rRg.aStart != pCopiedPaM->first.Start()->nNode) + { + // there is 1 (partially selected, maybe) paragraph before + assert(SwNodeIndex(rRg.aStart, -1) == pCopiedPaM->first.Start()->nNode); + // only use the passed in target SwPosition if the source PaM point + // is on a different node; if it was the same node then the target + // position was likely moved along by the copy operation and now + // points to the end of the range! + *aCpyPaM.GetPoint() = pCopiedPaM->second; + } - lcl_CopyBookmarks( - pCopiedPaM != NULL ? *pCopiedPaM : aRgTmp, - aCpyTmp ); + lcl_CopyBookmarks((pCopiedPaM) ? pCopiedPaM->first : aRgTmp, aCpyPaM); } if( bDelRedlines && ( nsRedlineMode_t::REDLINE_DELETE_REDLINES & pDest->getIDocumentRedlineAccess().GetRedlineMode() )) @@ -3194,6 +3207,12 @@ void DocumentContentOperationsManager::CopyWithFlyInFly( pDest->GetNodes()._DelDummyNodes( aCpyRange ); } +// TODO: there is a limitation here in that it's not possible to pass a start +// content index - which means that at-character anchored frames inside +// partial 1st paragraph of redline is not copied. +// But the DelFlyInRange() that is called from DelCopyOfSection() does not +// delete it either, and it also does not delete those on partial last para of +// redline, so copying those is supressed here too ... void DocumentContentOperationsManager::CopyFlyInFlyImpl( const SwNodeRange& rRg, const sal_Int32 nEndContentIndex, @@ -4390,16 +4409,26 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos, pDestTextNd->ResetAttr( RES_PAGEDESC ); } + SwPosition startPos(SwNodeIndex(pCopyPam->GetPoint()->nNode, +1), + SwIndex(SwNodeIndex(pCopyPam->GetPoint()->nNode, +1).GetNode().GetContentNode())); + if (bCanMoveBack) + { // pCopyPam is actually 1 before the copy range so move it fwd + SwPaM temp(*pCopyPam->GetPoint()); + temp.Move(fnMoveForward, fnGoContent); + startPos = *temp.GetPoint(); + } + assert(startPos.nNode.GetNode().IsContentNode()); + std::pair<SwPaM const&, SwPosition const&> tmp(rPam, startPos); if( aInsPos == pEnd->nNode ) { SwNodeIndex aSaveIdx( aInsPos, -1 ); - CopyWithFlyInFly( aRg, 0,aInsPos, &rPam, bMakeNewFrms, false ); + CopyWithFlyInFly( aRg, 0, aInsPos, &tmp, bMakeNewFrms, false ); ++aSaveIdx; pEnd->nNode = aSaveIdx; pEnd->nContent.Assign( aSaveIdx.GetNode().GetTextNode(), 0 ); } else - CopyWithFlyInFly( aRg, pEnd->nContent.GetIndex(), aInsPos, &rPam, bMakeNewFrms, false ); + CopyWithFlyInFly( aRg, pEnd->nContent.GetIndex(), aInsPos, &tmp, bMakeNewFrms, false ); bCopyBookmarks = false; diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx index 48f23840bbf2..3897b3fe24b2 100644 --- a/sw/source/core/inc/DocumentContentOperationsManager.hxx +++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx @@ -103,7 +103,7 @@ public: void CopyWithFlyInFly( const SwNodeRange& rRg, const sal_Int32 nEndContentIndex, const SwNodeIndex& rInsPos, - const SwPaM* pCopiedPaM = NULL, + const std::pair<const SwPaM&, const SwPosition&> * pCopiedPaM = nullptr, bool bMakeNewFrms = true, bool bDelRedlines = true, bool bCopyFlyAtFly = false ) const; |