[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - 2 commits - sw/inc sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Feb 21 09:37:13 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               |   29 ++++++++
 sw/qa/extras/uiwriter/uiwriter.cxx                      |    4 -
 sw/source/core/doc/DocumentContentOperationsManager.cxx |   53 ++++++++++++----
 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 |   10 +--
 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, 111 insertions(+), 44 deletions(-)

New commits:
commit 88d656833c29ff882b3207e7b55b5b5d0c3ac13a
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jan 10 16:03:43 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Feb 21 10:36:56 2020 +0100

    DOCX import: fix lost objects anchored to an empty linked header
    
    This is really similar to commit
    04b2310aaa094794ceedaa1bb6ff1823a2d29d3e (DOCX import: fix lost objects
    anchored to the single para of a linked header, 2020-01-10), except here
    the header is not just a single-paragraph one, but has no text portions.
    
    Update text-copy.docx to have a header which is not only a single
    paragraph, but also has no character content. This keeps testing the
    original case, but now also tests the more strict case (single paragraph
    -> single empty paragraph).
    
    (cherry picked from commit c12358166a9bd88fe10feabca45a6ad3f65dff8e)
    
    Change-Id: I11bb062e77af1a83f717225ea5b4daef39e5a672
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89153
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/extras/ooxmlimport/data/text-copy.docx b/sw/qa/extras/ooxmlimport/data/text-copy.docx
index 9c871e633517..03c0563b37fd 100644
Binary files a/sw/qa/extras/ooxmlimport/data/text-copy.docx 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 539c80d65863..e7d5fdaf87bf 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -280,6 +280,7 @@ 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.
+    // Note that the single paragraph itself has no text portions.
     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
                                                                   uno::UNO_QUERY);
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 1b115444f6be..daef8dc21300 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -1711,6 +1711,21 @@ DocumentContentOperationsManager::DocumentContentOperationsManager( SwDoc& i_rSw
 {
 }
 
+/**
+ * Checks if rStart..rEnd mark a range that makes sense to copy.
+ *
+ * bCopyText means that an empty range is OK, since paragraph-anchored objects may present.
+ */
+static bool IsEmptyRange(const SwPosition& rStart, const SwPosition& rEnd, bool bCopyText)
+{
+    bool bEmptyRange = rStart >= rEnd;
+    if (bCopyText)
+    {
+        bEmptyRange = rStart > rEnd;
+    }
+    return bEmptyRange;
+}
+
 // Copy an area into this document or into another document
 bool
 DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, const bool bCopyAll, bool bCheckPos, bool bCopyText ) const
@@ -1721,7 +1736,7 @@ DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, cons
     bool bColumnSel = pDoc->IsClipBoard() && pDoc->IsColumnSelection();
 
     // Catch if there's no copy to do
-    if( !rPam.HasMark() || ( *pStt >= *pEnd && !bColumnSel ) )
+    if (!rPam.HasMark() || (IsEmptyRange(*pStt, *pEnd, bCopyText) && !bColumnSel))
         return false;
 
     // Prevent copying in Flys that are anchored in the area
@@ -4405,7 +4420,7 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
     SwPosition *const pEnd = rPam.End();
 
     // Catch when there's no copy to do.
-    if( !rPam.HasMark() || ( *pStt >= *pEnd && !bColumnSel ) ||
+    if (!rPam.HasMark() || (IsEmptyRange(*pStt, *pEnd, bCopyText) && !bColumnSel) ||
         //JP 29.6.2001: 88963 - don't copy if inspos is in region of start to end
         //JP 15.11.2001: don't test inclusive the end, ever exclusive
         ( pDoc == &m_rDoc && *pStt <= rPos && rPos < *pEnd ))
commit 805577d0b67b9bc2d2cf7fe5424e611dbdd00d36
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 Feb 21 10:36:41 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.
    
    (cherry picked from commit 04b2310aaa094794ceedaa1bb6ff1823a2d29d3e)
    
    Conflicts:
            sw/source/core/doc/DocumentContentOperationsManager.cxx
            sw/source/core/inc/DocumentContentOperationsManager.hxx
    
    Change-Id: Id727f7ca4f6121a7050340359716a52ecb4886f2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89152
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index 161682891429..fec9c4b9ea64 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -108,7 +108,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 2008c1926275..ef8b2e10a9e2 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 110231888dee..539c80d65863 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -276,6 +276,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 a9687593ef10..457785382f02 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -732,7 +732,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());
@@ -748,7 +748,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 650c324dfb7a..1b115444f6be 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -1713,7 +1713,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();
 
@@ -1761,7 +1761,7 @@ DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, cons
 
     if( pDoc != &m_rDoc )
     {   // ordinary copy
-        bRet = CopyImpl( rPam, rPos, true, bCopyAll, pRedlineRange );
+        bRet = CopyImpl( rPam, rPos, true, bCopyAll, pRedlineRange, bCopyText );
     }
     else if( ! ( *pStt <= rPos && rPos < *pEnd &&
             ( pStt->nNode != pEnd->nNode ||
@@ -1769,7 +1769,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, true, bCopyAll, pRedlineRange );
+        bRet = CopyImpl( rPam, rPos, true, bCopyAll, pRedlineRange, bCopyText );
     }
     else
     {
@@ -1799,7 +1799,7 @@ DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, cons
                                 SwNodeIndex( m_rDoc.GetNodes().GetEndOfAutotext() ));
             aPam.GetPoint()->nNode = *pSttNd->EndOfSectionNode();
             // copy without Frames
-            pDoc->GetDocumentContentOperationsManager().CopyImpl( rPam, *aPam.GetPoint(), false, bCopyAll, nullptr );
+            pDoc->GetDocumentContentOperationsManager().CopyImpl( rPam, *aPam.GetPoint(), false, bCopyAll, nullptr, bCopyText );
 
             aPam.GetPoint()->nNode = pDoc->GetNodes().GetEndOfAutotext();
             aPam.SetMark();
@@ -3319,7 +3319,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);
@@ -3369,7 +3370,8 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
             (pCopiedPaM && rRg.aStart != pCopiedPaM->first.Start()->nNode)
                 ? pCopiedPaM->second.nNode
                 : aSavePos,
-            bCopyFlyAtFly);
+            bCopyFlyAtFly,
+            bCopyText);
     }
 
     SwNodeRange aCpyRange( aSavePos, rInsPos );
@@ -3407,7 +3409,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);
 
@@ -3442,9 +3445,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:
@@ -4384,7 +4395,8 @@ static void lcl_PopNumruleState( SfxItemState aNumRuleState, const SwNumRuleItem
 
 bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
         const bool bMakeNewFrames, 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();
@@ -4717,13 +4729,13 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
                 SwNodeIndex aSaveIdx( aInsPos, -1 );
                 assert(pStt->nNode != pEnd->nNode);
                 pEnd->nContent = 0; // TODO why this?
-                CopyWithFlyInFly( aRg, aInsPos, &tmp, bMakeNewFrames, false );
+                CopyWithFlyInFly( aRg, aInsPos, &tmp, bMakeNewFrames, false, /*bCopyFlyAtFly=*/false, bCopyText );
                 ++aSaveIdx;
                 pEnd->nNode = aSaveIdx;
                 pEnd->nContent.Assign( aSaveIdx.GetNode().GetTextNode(), 0 );
             }
             else
-                CopyWithFlyInFly( aRg, aInsPos, &tmp, bMakeNewFrames, false );
+                CopyWithFlyInFly( aRg, aInsPos, &tmp, bMakeNewFrames, false, /*bCopyFlyAtFly=*/false, bCopyText );
 
             bCopyBookmarks = false;
         }
diff --git a/sw/source/core/doc/doccomp.cxx b/sw/source/core/doc/doccomp.cxx
index c29a688ecb38..8ff506330726 100644
--- a/sw/source/core/doc/doccomp.cxx
+++ b/sw/source/core/doc/doccomp.cxx
@@ -1374,7 +1374,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() );
@@ -1941,7 +1941,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 e7c35433eb7d..58ea6f9e694e 100644
--- a/sw/source/core/doc/docglos.cxx
+++ b/sw/source/core/doc/docglos.cxx
@@ -187,7 +187,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 b8c91b4965fa..d6423740f508 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -445,7 +445,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 b176293ef3ff..4d36e33b50d4 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -1150,7 +1150,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 e99195f85a75..97b4622561df 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -2180,7 +2180,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 a09014d719ed..a3fabfaf514d 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -1465,7 +1465,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
@@ -1488,7 +1488,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 28c730d858a0..e4bfede103f0 100644
--- a/sw/source/core/docnode/section.cxx
+++ b/sw/source/core/docnode/section.cxx
@@ -1316,7 +1316,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 283a3f7dbd9c..dacf5ecf7f90 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 1a37235190a9..94b96416fae1 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -252,7 +252,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 2540672a9be3..a2f8e26d6dd3 100644
--- a/sw/source/core/edit/edglss.cxx
+++ b/sw/source/core/edit/edglss.cxx
@@ -142,7 +142,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();
         }
@@ -215,7 +215,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();
@@ -235,7 +235,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 9eb869de51ec..e812ca716bee 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -807,7 +807,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc )
             {
                 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),
@@ -1044,7 +1044,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc )
 
                     --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 edbd3c4e8154..2f3dab4bd2d8 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;
 
@@ -105,11 +105,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
@@ -166,7 +168,7 @@ private:
     /* Copy a range within the same or to another document.
      Position may not lie within range! */
     bool CopyImpl( SwPaM&, SwPosition&, const bool MakeNewFrames /*= true */,
-            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 a062f168acb0..5eeaa37180b0 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -1581,6 +1581,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 9e61a945e5fb..5e13149f86aa 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 2a84d8655a46..457e5265050a 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -2256,7 +2256,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
@@ -2267,7 +2270,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 188d15856dfd..ee7810e98351 100644
--- a/sw/source/filter/docx/swdocxreader.cxx
+++ b/sw/source/filter/docx/swdocxreader.cxx
@@ -239,7 +239,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 811b554c15a7..abe4b921a119 100644
--- a/sw/source/filter/ww8/ww8glsy.cxx
+++ b/sw/source/filter/ww8/ww8glsy.cxx
@@ -169,7 +169,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 2207d929a9c4..da12c7993943 100644
--- a/sw/source/filter/xml/xmltbli.cxx
+++ b/sw/source/filter/xml/xmltbli.cxx
@@ -704,7 +704,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 13f201c69c84..24620752f622 100644
--- a/sw/source/uibase/uno/unoatxt.cxx
+++ b/sw/source/uibase/uno/unoatxt.cxx
@@ -322,7 +322,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