[Libreoffice-commits] core.git: sw/inc sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Jan 10 13:13:39 UTC 2020


 sw/inc/IDocumentContentOperations.hxx                   |    2 
 sw/inc/undobj.hxx                                       |    3 -
 sw/qa/extras/ooxmlimport/data/text-copy.docx            |binary
 sw/qa/extras/ooxmlimport/ooxmlimport2.cxx               |   28 +++++++++++
 sw/qa/extras/uiwriter/uiwriter.cxx                      |    4 -
 sw/source/core/doc/DocumentContentOperationsManager.cxx |   40 ++++++++++------
 sw/source/core/doc/doccomp.cxx                          |    4 -
 sw/source/core/doc/docglos.cxx                          |    2 
 sw/source/core/doc/doclay.cxx                           |    2 
 sw/source/core/doc/docnew.cxx                           |    2 
 sw/source/core/doc/docnum.cxx                           |    2 
 sw/source/core/doc/docredln.cxx                         |    4 -
 sw/source/core/docnode/section.cxx                      |    2 
 sw/source/core/edit/acorrect.cxx                        |    2 
 sw/source/core/edit/eddel.cxx                           |    2 
 sw/source/core/edit/edglss.cxx                          |    6 +-
 sw/source/core/frmedt/fecopy.cxx                        |    4 -
 sw/source/core/inc/DocumentContentOperationsManager.hxx |   12 ++--
 sw/source/core/undo/undobj.cxx                          |    5 ++
 sw/source/core/undo/untblk.cxx                          |    2 
 sw/source/core/unocore/unotext.cxx                      |    7 ++
 sw/source/filter/docx/swdocxreader.cxx                  |    2 
 sw/source/filter/ww8/ww8glsy.cxx                        |    2 
 sw/source/filter/xml/xmltbli.cxx                        |    2 
 sw/source/uibase/uno/unoatxt.cxx                        |    2 
 25 files changed, 97 insertions(+), 46 deletions(-)

New commits:
commit 04b2310aaa094794ceedaa1bb6ff1823a2d29d3e
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jan 10 13:20:40 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Jan 10 14:13:05 2020 +0100

    DOCX import: fix lost objects anchored to the single para of a linked header
    
    Regression from commit 08f13ab85b5c65b5dc8adfa15918fb3e426fcc3c
    (tdf#112202 writerfilter,sw: fix loss of headers, 2019-12-16), the
    problem is that on one hand, copyText() is meant to copy a complete
    XText (header, table cell, footnote, etc), OTOH the internal API use
    used only copies at-para anchored objects for complete text nodes, so a
    one-paragraph header will loose its anchored objects when a linked
    header is copied.
    
    Introduce a new "CopyText" flag that provides the expected copyText()
    behavior and use that when the copyText() UNO API is invoked, but leave
    the selection behavior unchanged.
    
    Perform the inclusive check in IsSelectFrameAnchoredAtPara(), opt in for
    that from SwXText::copyText(), the rest is just passing the flag around.
    
    Change-Id: Id727f7ca4f6121a7050340359716a52ecb4886f2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86529
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index f59b1f0eef89..6ba51df9f740 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -109,7 +109,7 @@ public:
         rPam. If false, then no such check will be performed, and it is assumed
         that the caller took care of verifying this constraint already.
      */
-    virtual bool CopyRange(SwPaM& rPam, SwPosition& rPos, const bool bCopyAll, bool bCheckPos ) const = 0;
+    virtual bool CopyRange(SwPaM& rPam, SwPosition& rPos, const bool bCopyAll, bool bCheckPos, bool bCopyText ) const = 0;
 
     /** Delete section containing the node.
     */
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx
index cde1e3a0ff35..5f261f68e8eb 100644
--- a/sw/inc/undobj.hxx
+++ b/sw/inc/undobj.hxx
@@ -137,9 +137,10 @@ enum class DelContentType : sal_uInt16
     AllMask      = 0x0b,
     ExcludeFlyAtStartEnd = 0x40,
     CheckNoCntnt = 0x80,
+    CopyText = 0x100,
 };
 namespace o3tl {
-    template<> struct typed_flags<DelContentType> : is_typed_flags<DelContentType, 0xcb> {};
+    template<> struct typed_flags<DelContentType> : is_typed_flags<DelContentType, 0x1cb> {};
 }
 
 /// will DelContentIndex destroy a frame anchored at character at rAnchorPos?
diff --git a/sw/qa/extras/ooxmlimport/data/text-copy.docx b/sw/qa/extras/ooxmlimport/data/text-copy.docx
new file mode 100644
index 000000000000..9c871e633517
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/text-copy.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index f5ff5b3b53e8..11243d14e33d 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -283,6 +283,34 @@ DECLARE_OOXMLIMPORT_TEST(testTdf124754, "tdf124754.docx")
                                  getProperty<sal_Int32>(xText, "CharColor"));
 }
 
+DECLARE_OOXMLIMPORT_TEST(testTextCopy, "text-copy.docx")
+{
+    // The document has a header on the second page that is copied as part of the import process.
+    // The header has a single paragraph: make sure shapes anchored to it are not lost.
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+                                                                  uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+    uno::Reference<beans::XPropertySet> xPara;
+    while (xParaEnum->hasMoreElements())
+    {
+        xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+    }
+    auto aPageStyleName = getProperty<OUString>(xPara, "PageStyleName");
+    uno::Reference<beans::XPropertySet> xPageStyle(
+        getStyles("PageStyles")->getByName(aPageStyleName), uno::UNO_QUERY);
+    auto xHeaderText = getProperty<uno::Reference<text::XText>>(xPageStyle, "HeaderText");
+    uno::Reference<container::XContentEnumerationAccess> xHeaderPara(
+        getParagraphOfText(1, xHeaderText), uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xHeaderShapes
+        = xHeaderPara->createContentEnumeration("com.sun.star.text.TextContent");
+    // Without the accompanying fix in place, this test would have failed with:
+    // assertion failed
+    // - Expression: xHeaderShapes->hasMoreElements()
+    // i.e. the second page's header had no anchored shapes.
+    CPPUNIT_ASSERT(xHeaderShapes->hasMoreElements());
+}
+
 DECLARE_OOXMLIMPORT_TEST(testTdf112443, "tdf112443.docx")
 {
     // the position of the flying text frame should be off page
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index db26e92aca24..76a1054c441a 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -748,7 +748,7 @@ void SwUiWriterTest::testBookmarkCopy()
     aPaM.SttEndDoc(true/*start*/);
     aPaM.Move(fnMoveForward, GoInContent); // partially select 1st para
 
-    rIDCO.CopyRange(aPaM, target, /*bCopyAll=*/false, /*bCheckPos=*/true);
+    rIDCO.CopyRange(aPaM, target, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false);
 
     // check bookmark was copied to correct position
     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), rIDMA.getBookmarksCount());
@@ -764,7 +764,7 @@ void SwUiWriterTest::testBookmarkCopy()
     rIDCO.SplitNode(*aPaM.GetPoint(), false);
     aPaM.SttEndDoc(true/*start*/);
 
-    rIDCO.CopyRange(aCopyPaM, *aPaM.GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true);
+    rIDCO.CopyRange(aCopyPaM, *aPaM.GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false);
 
     // check bookmark was copied to correct position
     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rIDMA.getBookmarksCount());
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 5c2b745161ff..1d56e41dde50 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -1830,7 +1830,7 @@ DocumentContentOperationsManager::DocumentContentOperationsManager( SwDoc& i_rSw
 
 // Copy an area into this document or into another document
 bool
-DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, const bool bCopyAll, bool bCheckPos ) const
+DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, const bool bCopyAll, bool bCheckPos, bool bCopyText ) const
 {
     const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
 
@@ -1878,7 +1878,7 @@ DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, cons
 
     if( pDoc != &m_rDoc )
     {   // ordinary copy
-        bRet = CopyImpl( rPam, rPos, bCopyAll, pRedlineRange );
+        bRet = CopyImpl( rPam, rPos, bCopyAll, pRedlineRange, bCopyText );
     }
     else if( ! ( *pStt <= rPos && rPos < *pEnd &&
             ( pStt->nNode != pEnd->nNode ||
@@ -1886,7 +1886,7 @@ DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, cons
     {
         // Copy to a position outside of the area, or copy a single TextNode
         // Do an ordinary copy
-        bRet = CopyImpl( rPam, rPos, bCopyAll, pRedlineRange );
+        bRet = CopyImpl( rPam, rPos, bCopyAll, pRedlineRange, bCopyText );
     }
     else
     {
@@ -3361,7 +3361,8 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
     const std::pair<const SwPaM&, const SwPosition&>* pCopiedPaM /*and real insert pos*/,
     const bool bMakeNewFrames,
     const bool bDelRedlines,
-    const bool bCopyFlyAtFly ) const
+    const bool bCopyFlyAtFly,
+    bool bCopyText ) const
 {
     assert(!pCopiedPaM || pCopiedPaM->first.End()->nNode == rRg.aEnd);
     assert(!pCopiedPaM || pCopiedPaM->second.nNode <= rInsPos);
@@ -3411,7 +3412,8 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
             (pCopiedPaM && rRg.aStart != pCopiedPaM->first.Start()->nNode)
                 ? pCopiedPaM->second.nNode
                 : aSavePos,
-            bCopyFlyAtFly);
+            bCopyFlyAtFly,
+            bCopyText);
     }
 
     SwNodeRange aCpyRange( aSavePos, rInsPos );
@@ -3449,7 +3451,8 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl(
     const SwNodeRange& rRg,
     SwPaM const*const pCopiedPaM,
     const SwNodeIndex& rStartIdx,
-    const bool bCopyFlyAtFly ) const
+    const bool bCopyFlyAtFly,
+    bool bCopyText ) const
 {
     assert(!pCopiedPaM || pCopiedPaM->End()->nNode == rRg.aEnd);
 
@@ -3484,9 +3487,17 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl(
             break;
             case RndStdIds::FLY_AT_PARA:
                 {
+                    DelContentType eDelContentType = DelContentType::AllMask;
+                    if (bCopyText)
+                    {
+                        // Called from SwXText::copyText(), select the frame if rAnchorPos is inside
+                        // the range, inclusive.
+                        eDelContentType = DelContentType::CopyText;
+                    }
                     bAdd = IsSelectFrameAnchoredAtPara(*pAPos,
                         pCopiedPaM ? *pCopiedPaM->Start() : SwPosition(rRg.aStart),
-                        pCopiedPaM ? *pCopiedPaM->End() : SwPosition(rRg.aEnd));
+                        pCopiedPaM ? *pCopiedPaM->End() : SwPosition(rRg.aEnd),
+                        eDelContentType);
                 }
             break;
             case RndStdIds::FLY_AT_CHAR:
@@ -4438,7 +4449,8 @@ static void lcl_PopNumruleState(
 
 bool DocumentContentOperationsManager::CopyImpl(SwPaM& rPam, SwPosition& rPos,
         const bool bCopyAll,
-        SwPaM *const pCopyRange) const
+        SwPaM *const pCopyRange,
+        bool bCopyText) const
 {
     std::vector<std::pair<sal_uLong, sal_Int32>> Breaks;
 
@@ -4446,7 +4458,7 @@ bool DocumentContentOperationsManager::CopyImpl(SwPaM& rPam, SwPosition& rPos,
 
     if (Breaks.empty())
     {
-        return CopyImplImpl(rPam, rPos, bCopyAll, pCopyRange);
+        return CopyImplImpl(rPam, rPos, bCopyAll, pCopyRange, bCopyText);
     }
 
     SwPosition const & rSelectionEnd( *rPam.End() );
@@ -4468,7 +4480,7 @@ bool DocumentContentOperationsManager::CopyImpl(SwPaM& rPam, SwPosition& rPos,
         if (rStart < rEnd) // check if part is empty
         {
             // pass in copyRange member as rPos; should work ...
-            bRet &= CopyImplImpl(aPam, *copyRange.Start(), bCopyAll, &copyRange);
+            bRet &= CopyImplImpl(aPam, *copyRange.Start(), bCopyAll, &copyRange, /*bCopyText=*/false);
             nOffset = iter->first - rStart.nNode.GetIndex(); // fly nodes...
             if (pCopyRange)
             {
@@ -4488,7 +4500,7 @@ bool DocumentContentOperationsManager::CopyImpl(SwPaM& rPam, SwPosition& rPos,
     rStart = *rPam.Start(); // set to original start
     if (rStart < rEnd) // check if part is empty
     {
-        bRet &= CopyImplImpl(aPam, *copyRange.Start(), bCopyAll, &copyRange);
+        bRet &= CopyImplImpl(aPam, *copyRange.Start(), bCopyAll, &copyRange, /*bCopyText=*/false);
         if (pCopyRange)
         {
             if (bFirst)
@@ -4505,7 +4517,7 @@ bool DocumentContentOperationsManager::CopyImpl(SwPaM& rPam, SwPosition& rPos,
 
 bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPos,
         const bool bCopyAll,
-        SwPaM *const pCpyRange ) const
+        SwPaM *const pCpyRange, bool bCopyText ) const
 {
     SwDoc* pDoc = rPos.nNode.GetNode().GetDoc();
     const bool bColumnSel = pDoc->IsClipBoard() && pDoc->IsColumnSelection();
@@ -4838,13 +4850,13 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo
                 SwNodeIndex aSaveIdx( aInsPos, -1 );
                 assert(pStt->nNode != pEnd->nNode);
                 pEnd->nContent = 0; // TODO why this?
-                CopyWithFlyInFly( aRg, aInsPos, &tmp, /*bMakeNewFrames*/true, false );
+                CopyWithFlyInFly( aRg, aInsPos, &tmp, /*bMakeNewFrames*/true, false, /*bCopyFlyAtFly=*/false, bCopyText );
                 ++aSaveIdx;
                 pEnd->nNode = aSaveIdx;
                 pEnd->nContent.Assign( aSaveIdx.GetNode().GetTextNode(), 0 );
             }
             else
-                CopyWithFlyInFly( aRg, aInsPos, &tmp, /*bMakeNewFrames*/true, false );
+                CopyWithFlyInFly( aRg, aInsPos, &tmp, /*bMakeNewFrames*/true, false, /*bCopyFlyAtFly=*/false, bCopyText );
 
             bCopyBookmarks = false;
         }
diff --git a/sw/source/core/doc/doccomp.cxx b/sw/source/core/doc/doccomp.cxx
index 2fcf30ad8412..22d2b85ed977 100644
--- a/sw/source/core/doc/doccomp.cxx
+++ b/sw/source/core/doc/doccomp.cxx
@@ -1376,7 +1376,7 @@ bool SwCompareLine::ChangesInLine( const SwCompareLine& rLine,
                 aCpyPam.SetMark();
                 aCpyPam.GetPoint()->nContent = nSrcTo;
                 aCpyPam.GetDoc()->getIDocumentContentOperations().CopyRange( aCpyPam, *aPam.GetPoint(),
-                    /*bCopyAll=*/false, /*bCheckPos=*/true );
+                    /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
                 pDstDoc->GetIDocumentUndoRedo().DoUndo( bUndo );
 
                 SwPaM* pTmp = new SwPaM( *aPam.GetPoint(), rpDelRing.get() );
@@ -1943,7 +1943,7 @@ sal_uInt16 SaveMergeRedline::InsertRedline(SwPaM* pLastDestRedline)
 
         pSrcRedl->GetDoc()->getIDocumentContentOperations().CopyRange(
                 *const_cast<SwPaM*>(static_cast<const SwPaM*>(pSrcRedl)),
-                *pDestRedl->GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true );
+                *pDestRedl->GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
 
         pDoc->getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld );
 
diff --git a/sw/source/core/doc/docglos.cxx b/sw/source/core/doc/docglos.cxx
index 56e8533f24f2..f034d289a5ed 100644
--- a/sw/source/core/doc/docglos.cxx
+++ b/sw/source/core/doc/docglos.cxx
@@ -189,7 +189,7 @@ bool SwDoc::InsertGlossary( SwTextBlocks& rBlock, const OUString& rEntry,
                 SwDontExpandItem aACD;
                 aACD.SaveDontExpandItems( rInsPos );
 
-                pGDoc->getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+                pGDoc->getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
 
                 aACD.RestoreDontExpandItems( rInsPos );
                 if( pShell )
diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index 4ff478498dcc..85b1229b4d5a 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -428,7 +428,7 @@ SwFlyFrameFormat* SwDoc::MakeFlyAndMove( const SwPaM& rPam, const SfxItemSet& rS
                         *rTmp.GetPoint() != *rTmp.GetMark() )
                     {
                         // aPos is the newly created fly section, so definitely outside rPam, it's pointless to check that again.
-                        getIDocumentContentOperations().CopyRange( *const_cast<SwPaM*>(&rTmp), aPos, /*bCopyAll=*/false, /*bCheckPos=*/false );
+                        getIDocumentContentOperations().CopyRange( *const_cast<SwPaM*>(&rTmp), aPos, /*bCopyAll=*/false, /*bCheckPos=*/false, /*bCopyText=*/false );
                     }
                 }
                 getIDocumentRedlineAccess().SetRedlineMove(bOldRedlineMove);
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 0e449883fd2c..1547ebf19abc 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -1143,7 +1143,7 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, sal_uInt16 const nStartPageNu
 #ifdef DBG_UTIL
             SAL_INFO( "sw.docappend", "CopyRange In: " << CNTNT_DOC( this ) );
 #endif
-            rSource.getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, /*bCopyAll=*/true, /*bCheckPos=*/true );
+            rSource.getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, /*bCopyAll=*/true, /*bCheckPos=*/true, /*bCopyText=*/false );
             // Note: aCpyPam is invalid now
 #ifdef DBG_UTIL
             SAL_INFO( "sw.docappend", "CopyRange Out: " << CNTNT_DOC( this ) );
diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index a27d0a87122e..d0efa05bb990 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -2170,7 +2170,7 @@ bool SwDoc::MoveParagraphImpl(SwPaM& rPam, long const nOffset,
 
             --aIdx; // move before insertion
 
-            getIDocumentContentOperations().CopyRange( aPam, aInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+            getIDocumentContentOperations().CopyRange( aPam, aInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
 
             // now delete all the delete redlines that were copied
 #ifndef NDEBUG
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index e101bdc65b9e..ee8e8b23d8c0 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -1404,7 +1404,7 @@ void SwRangeRedline::CopyToSection()
         SwNodeIndex aNdIdx( *pSttNd, 1 );
         SwTextNode* pTextNd = aNdIdx.GetNode().GetTextNode();
         SwPosition aPos( aNdIdx, SwIndex( pTextNd ));
-        pDoc->getIDocumentContentOperations().CopyRange( *this, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+        pDoc->getIDocumentContentOperations().CopyRange( *this, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
 
         // Take over the style from the EndNode if needed
         // We don't want this in Doc::Copy
@@ -1427,7 +1427,7 @@ void SwRangeRedline::CopyToSection()
         if( pCEndNd )
         {
             SwPosition aPos( *pSttNd->EndOfSectionNode() );
-            pDoc->getIDocumentContentOperations().CopyRange( *this, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+            pDoc->getIDocumentContentOperations().CopyRange( *this, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
         }
         else
         {
diff --git a/sw/source/core/docnode/section.cxx b/sw/source/core/docnode/section.cxx
index 050edf187f36..e38e196acff2 100644
--- a/sw/source/core/docnode/section.cxx
+++ b/sw/source/core/docnode/section.cxx
@@ -1321,7 +1321,7 @@ static void lcl_UpdateLinksInSect( SwBaseLink& rUpdLnk, SwSectionNode& rSectNd )
                             pCpyPam->Start()->nNode > rInsPos ||
                             rInsPos >= pCpyPam->End()->nNode )
                         {
-                            pSrcDoc->getIDocumentContentOperations().CopyRange( *pCpyPam, *pPam->GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true );
+                            pSrcDoc->getIDocumentContentOperations().CopyRange( *pCpyPam, *pPam->GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
                         }
                         delete pCpyPam;
                     }
diff --git a/sw/source/core/edit/acorrect.cxx b/sw/source/core/edit/acorrect.cxx
index 95e3a7e98b69..5cb118744d70 100644
--- a/sw/source/core/edit/acorrect.cxx
+++ b/sw/source/core/edit/acorrect.cxx
@@ -467,7 +467,7 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos,
                 SwDontExpandItem aExpItem;
                 aExpItem.SaveDontExpandItems( *aPam.GetPoint() );
 
-                pAutoDoc->getIDocumentContentOperations().CopyRange( aCpyPam, *aPam.GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true );
+                pAutoDoc->getIDocumentContentOperations().CopyRange( aCpyPam, *aPam.GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
 
                 aExpItem.RestoreDontExpandItems( *aPam.GetPoint() );
 
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index e1f30a275ead..a2d5249daab3 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -245,7 +245,7 @@ bool SwEditShell::Copy( SwEditShell* pDestShell )
             bFirstMove = false;
         }
 
-        const bool bSuccess( GetDoc()->getIDocumentContentOperations().CopyRange( rPaM, *pPos, /*bCopyAll=*/false, /*bCheckPos=*/true ) );
+        const bool bSuccess( GetDoc()->getIDocumentContentOperations().CopyRange( rPaM, *pPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false ) );
         if (!bSuccess)
             continue;
 
diff --git a/sw/source/core/edit/edglss.cxx b/sw/source/core/edit/edglss.cxx
index 45e8043e13e5..7d691913435a 100644
--- a/sw/source/core/edit/edglss.cxx
+++ b/sw/source/core/edit/edglss.cxx
@@ -137,7 +137,7 @@ sal_uInt16 SwEditShell::SaveGlossaryDoc( SwTextBlocks& rBlock,
             aStt = pGDoc->GetNodes().GetEndOfExtras();
             pContentNd = pGDoc->GetNodes().GoNext( &aStt );
             SwPosition aInsPos( aStt, SwIndex( pContentNd ));
-            pMyDoc->getIDocumentContentOperations().CopyRange( aCpyPam, aInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+            pMyDoc->getIDocumentContentOperations().CopyRange( aCpyPam, aInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
 
             nRet = rBlock.PutDoc();
         }
@@ -210,7 +210,7 @@ bool SwEditShell::CopySelToDoc( SwDoc* pInsDoc )
                     {
                         rPaM.SetMark();
                         rPaM.Move( fnMoveForward, GoInContent );
-                        bRet = GetDoc()->getIDocumentContentOperations().CopyRange( rPaM, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true )
+                        bRet = GetDoc()->getIDocumentContentOperations().CopyRange( rPaM, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false )
                             || bRet;
                         rPaM.Exchange();
                         rPaM.DeleteMark();
@@ -230,7 +230,7 @@ bool SwEditShell::CopySelToDoc( SwDoc* pInsDoc )
                         aPaM.Start()->nNode = aPaM.Start()->nNode.GetNode().FindTableNode()->GetIndex();
                         aPaM.Start()->nContent.Assign(nullptr, 0);
                     }
-                    bRet = GetDoc()->getIDocumentContentOperations().CopyRange( aPaM, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true ) || bRet;
+                    bRet = GetDoc()->getIDocumentContentOperations().CopyRange( aPaM, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false ) || bRet;
                 }
             }
         }
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index ed91aa86b851..51e344890885 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -798,7 +798,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc, bool bNestedTable )
             {
                 SwNodeIndex aIndexBefore(rInsPos.nNode);
                 --aIndexBefore;
-                pClpDoc->getIDocumentContentOperations().CopyRange( rCopy, rInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+                pClpDoc->getIDocumentContentOperations().CopyRange( rCopy, rInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
                 {
                     ++aIndexBefore;
                     SwPaM aPaM(SwPosition(aIndexBefore),
@@ -1037,7 +1037,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc, bool bNestedTable )
 
                     --aIndexBefore;
 
-                    pClpDoc->getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+                    pClpDoc->getIDocumentContentOperations().CopyRange( aCpyPam, rInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
                     // Note: aCpyPam is invalid now
 
                     ++aIndexBefore;
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index 21829eaf22a5..4f523bec9f3d 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -37,7 +37,7 @@ public:
     DocumentContentOperationsManager( SwDoc& i_rSwdoc );
 
     //Interface methods:
-    bool CopyRange(SwPaM&, SwPosition&, const bool bCopyAll, bool bCheckPos ) const override;
+    bool CopyRange(SwPaM&, SwPosition&, const bool bCopyAll, bool bCheckPos, bool bCopyText ) const override;
 
     void DeleteSection(SwNode* pNode) override;
 
@@ -108,11 +108,13 @@ public:
                             const std::pair<const SwPaM&, const SwPosition&> * pCopiedPaM = nullptr,
                             bool bMakeNewFrames = true,
                             bool bDelRedlines = true,
-                            bool bCopyFlyAtFly = false ) const;
+                            bool bCopyFlyAtFly = false,
+                            bool bCopyText = false ) const;
     void CopyFlyInFlyImpl(  const SwNodeRange& rRg,
                             SwPaM const*const pCopiedPaM,
                             const SwNodeIndex& rStartIdx,
-                            const bool bCopyFlyAtFly = false ) const;
+                            const bool bCopyFlyAtFly = false,
+                            bool bCopyText = false ) const;
 
     /// Parameters for _Rst and lcl_SetTextFormatColl
     //originallyfrom docfmt.cxx
@@ -169,9 +171,9 @@ private:
     /* Copy a range within the same or to another document.
      Position may not lie within range! */
     bool CopyImpl( SwPaM&, SwPosition&,
-            const bool bCopyAll, SwPaM *const pCpyRng /*= 0*/ ) const;
+            const bool bCopyAll, SwPaM *const pCpyRng /*= 0*/, bool bCopyText ) const;
     bool CopyImplImpl(SwPaM&, SwPosition&,
-            const bool bCopyAll, SwPaM *const pCpyRng /*= 0*/) const;
+            const bool bCopyAll, SwPaM *const pCpyRng /*= 0*/, bool bCopyText ) const;
 
     DocumentContentOperationsManager(DocumentContentOperationsManager const&) = delete;
     DocumentContentOperationsManager& operator=(DocumentContentOperationsManager const&) = delete;
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index ec345897a303..5831f8bfea89 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -1592,6 +1592,11 @@ bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos,
             && (rStart.nNode <= rAnchorPos.nNode);
     }
 
+    if (nDelContentType == DelContentType::CopyText)
+    {
+        return (rStart.nNode <= rAnchorPos.nNode) && (rAnchorPos.nNode <= rEnd.nNode);
+    }
+
     if (rAnchorPos.GetDoc()->IsInReading())
     {   // FIXME hack for writerfilter RemoveLastParagraph(); can't test file format more specific?
         // but it MUST NOT be done during the SetRedlineFlags at the end of ODF
diff --git a/sw/source/core/undo/untblk.cxx b/sw/source/core/undo/untblk.cxx
index cd1315b59cd0..05a2080aec39 100644
--- a/sw/source/core/undo/untblk.cxx
+++ b/sw/source/core/undo/untblk.cxx
@@ -421,7 +421,7 @@ void SwUndoInserts::RepeatImpl(::sw::RepeatContext & rContext)
     SwPaM aPam( rContext.GetDoc().GetNodes().GetEndOfContent() );
     SetPaM( aPam );
     SwPaM & rRepeatPaM( rContext.GetRepeatPaM() );
-    aPam.GetDoc()->getIDocumentContentOperations().CopyRange( aPam, *rRepeatPaM.GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true );
+    aPam.GetDoc()->getIDocumentContentOperations().CopyRange( aPam, *rRepeatPaM.GetPoint(), /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
 }
 
 SwUndoInsDoc::SwUndoInsDoc( const SwPaM& rPam )
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index 8df24a11b701..0c98cae57a3e 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -2249,7 +2249,10 @@ SwXText::copyText(
             {
                 pNode->MakeEndIndex(&temp.GetPoint()->nContent);
             }
-            m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, /*bCopyAll=*/false, /*bCheckPos=*/true);
+            // Explicitly request copy text mode, so
+            // sw::DocumentContentOperationsManager::CopyFlyInFlyImpl() will copy shapes anchored to
+            // us, even if we have only a single paragraph.
+            m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/true);
         }
         if (!pFirstNode)
         {   // the node at rPos was split; get rid of the first empty one so
@@ -2260,7 +2263,7 @@ SwXText::copyText(
     }
     else
     {
-        m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(*pCursor->GetPaM(), rPos, /*bCopyAll=*/false, /*bCheckPos=*/true);
+        m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(*pCursor->GetPaM(), rPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/true);
     }
 
 }
diff --git a/sw/source/filter/docx/swdocxreader.cxx b/sw/source/filter/docx/swdocxreader.cxx
index f13127fcabd7..ce04767173ad 100644
--- a/sw/source/filter/docx/swdocxreader.cxx
+++ b/sw/source/filter/docx/swdocxreader.cxx
@@ -233,7 +233,7 @@ bool SwDOCXReader::MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks )
                     SwNodeIndex aIdx( pGlDoc->GetNodes().GetEndOfContent(), -1 );
                     pCNd = aIdx.GetNode().GetContentNode();
                     SwPosition aPos( aIdx, SwIndex( pCNd, pCNd ? pCNd->Len() : 0 ) );
-                    pD->getIDocumentContentOperations().CopyRange( aPam, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+                    pD->getIDocumentContentOperations().CopyRange( aPam, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
                     rBlocks.PutDoc();
                 }
                 else
diff --git a/sw/source/filter/ww8/ww8glsy.cxx b/sw/source/filter/ww8/ww8glsy.cxx
index 7606b2436797..cb23b4ac8d41 100644
--- a/sw/source/filter/ww8/ww8glsy.cxx
+++ b/sw/source/filter/ww8/ww8glsy.cxx
@@ -167,7 +167,7 @@ bool WW8Glossary::MakeEntries(SwDoc *pD, SwTextBlocks &rBlocks,
                         -1 );
                     pCNd = aIdx.GetNode().GetContentNode();
                     SwPosition aPos(aIdx, SwIndex(pCNd, pCNd ? pCNd->Len() : 0));
-                    pD->getIDocumentContentOperations().CopyRange( aPam, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+                    pD->getIDocumentContentOperations().CopyRange( aPam, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
                     rBlocks.PutDoc();
                 }
             }
diff --git a/sw/source/filter/xml/xmltbli.cxx b/sw/source/filter/xml/xmltbli.cxx
index bc815b7a098d..922815d5f94e 100644
--- a/sw/source/filter/xml/xmltbli.cxx
+++ b/sw/source/filter/xml/xmltbli.cxx
@@ -686,7 +686,7 @@ void SwXMLTableCellContext_Impl::EndElement()
                     assert(pDstTextCursor && "SwXTextCursor missing");
                     SwPaM aSrcPaM(*pSrcPaM->GetMark(), *pSrcPaM->GetPoint());
                     SwPosition aDstPos( *pDstTextCursor->GetPaM()->GetPoint() );
-                    pDoc->getIDocumentContentOperations().CopyRange( aSrcPaM, aDstPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
+                    pDoc->getIDocumentContentOperations().CopyRange( aSrcPaM, aDstPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false );
 
                     m_nColRepeat--;
                 }
diff --git a/sw/source/uibase/uno/unoatxt.cxx b/sw/source/uibase/uno/unoatxt.cxx
index d226b52ae31d..fccaef19acba 100644
--- a/sw/source/uibase/uno/unoatxt.cxx
+++ b/sw/source/uibase/uno/unoatxt.cxx
@@ -317,7 +317,7 @@ static bool lcl_CopySelToDoc( SwDoc* pInsDoc, OTextCursorHelper* pxCursor, SwXTe
             }
         }
         if (!pPam) { return false; }
-        bRet = pDoc->getIDocumentContentOperations().CopyRange( *pPam, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true ) || bRet;
+        bRet = pDoc->getIDocumentContentOperations().CopyRange( *pPam, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false ) || bRet;
     }
 
     pInsDoc->getIDocumentFieldsAccess().UnlockExpFields();


More information about the Libreoffice-commits mailing list