sw/inc/IDocumentContentOperations.hxx                   |    3 --
 sw/inc/strings.hrc                                      |    2 +
 sw/qa/core/doc/doc.cxx                                  |   24 ++++++++++------
 sw/source/core/doc/DocumentContentOperationsManager.cxx |   16 ++--------
 sw/source/core/doc/docbm.cxx                            |    4 ++
 sw/source/core/doc/docdesc.cxx                          |    4 +-
 sw/source/core/doc/docfmt.cxx                           |    2 -
 sw/source/core/inc/DocumentContentOperationsManager.hxx |    2 -
 sw/source/core/unocore/unotext.cxx                      |   22 ++------------
 writerfilter/source/dmapper/PropertyMap.cxx             |   11 -------
 10 files changed, 33 insertions(+), 57 deletions(-)

New commits:
commit 41403fbff8140ad0ca7cf8f81d37cddcfbd19197
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Oct 13 13:53:33 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Oct 13 15:16:04 2022 +0200

    sw: improve duplicated bookmarks in copied header/footer text
    
    Bookmarks in copied text were renamed in a way that made it hard to
    differentiate between the original bookmark and the copy, e.g. "Bookmark
    1" was renamed to "Bookmark 11".
    
    Bookmarks are supposed to have a unique name, so renaming makes sense,
    and it's probably better to do that compared to what commit
    3ec224dcb15e0e663ba85077b8ea0e632f8f03f8 (DOCX import: avoid duplicated
    bookmarks in copied header/footer text, 2022-09-08) did to just omit
    them during copy. That solved the duplicated bookmarks, but if one had
    bookmarks around images to find them, now it doesn't work to find all
    such images.
    
    Fix the problem by going back to copying bookmarks, but copy "Bookmark
    1" as "Bookmark 1 Copy 1" (and "Bookmark 1 Copy 2", etc), so API users
    can identify the original and the copied bookmarks.
    
    A similar problem is there for images as well, but that's not yet
    addressed here.
    
    Change-Id: Ic0689b05f790a99ff06523ff4836b1dd412af896
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141293
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/IDocumentContentOperations.hxx 
b/sw/inc/IDocumentContentOperations.hxx
index 60d45d47a0a3..5a95d0ba95b8 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -75,12 +75,11 @@ enum class SwCopyFlags
     CopyAll         = (1<<0), ///< copy break attributes even when source is 
single node
     CheckPosInFly   = (1<<1), ///< check if target position is in fly anchored 
at source range
     IsMoveToFly     = (1<<2), ///< MakeFlyAndMove
-    SkipBookmarks   = (1<<3), ///< skip bookmarks, but not other kind of marks
     // TODO: mbCopyIsMove? mbIsRedlineMove?
 };
 namespace o3tl
 {
-    template<> struct typed_flags<SwCopyFlags> : is_typed_flags<SwCopyFlags, 
0x0f> {};
+    template<> struct typed_flags<SwCopyFlags> : is_typed_flags<SwCopyFlags, 
0x07> {};
 }
 
 enum class SwDeleteFlags
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index 4f2dd39ff86b..e1859f1432d0 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -1446,6 +1446,8 @@
 // in order to change %PRODUCTNAME at runtime is expensive, so limit doing 
that as much as possible.
 #define STR_A11Y_DESC_AUTO                  
NC_("insertcaption|extended_tip|auto", "Opens the Caption dialog. It has the 
same information as the dialog you get by menu %PRODUCTNAME Writer - 
AutoCaption in the Options dialog box.")
 
+#define STR_MARK_COPY NC_("STR_MARK_COPY", "%1 Copy ")
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/doc/data/copy-flag-skip-bookmarks.docx 
b/sw/qa/core/doc/data/copy-bookmarks.docx
similarity index 100%
rename from sw/qa/core/doc/data/copy-flag-skip-bookmarks.docx
rename to sw/qa/core/doc/data/copy-bookmarks.docx
diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx
index 8c882e906373..98548befa9ee 100644
--- a/sw/qa/core/doc/doc.cxx
+++ b/sw/qa/core/doc/doc.cxx
@@ -256,19 +256,27 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, 
testContentControlDelete)
     CPPUNIT_ASSERT_EQUAL(OUString("\x0001test\x0001"), pTextNode->GetText());
 }
 
-CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testCopyFlagSkipBookmarks)
+CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testCopyBookmarks)
 {
     // Given a document with a bookmark in a header that is linked later:
-    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "copy-flag-skip-bookmarks.docx");
-
-    // When checking the # of bookmarks in the resulting doc model:
-    sal_Int32 nActual = pDoc->getIDocumentMarkAccess()->getAllMarksCount();
-
-    // Then make sure we have a single bookmark, with no duplications:
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "copy-bookmarks.docx");
+
+    // When checking the # of non-copy bookmarks in the resulting doc model:
+    sal_Int32 nActual = 0;
+    for (auto it = pDoc->getIDocumentMarkAccess()->getBookmarksBegin();
+         it != pDoc->getIDocumentMarkAccess()->getBookmarksEnd(); ++it)
+    {
+        if ((*it)->GetName().indexOf("Copy") == -1)
+        {
+            ++nActual;
+        }
+    }
+
+    // Then make sure we have a single non-copy bookmark, with no duplications:
     // Without the accompanying fix in place, this test would have failed with:
     // - Expected: 1
     // - Actual  : 2
-    // i.e. the 2nd header had a duplicated bookmark.
+    // i.e. the 2nd header had a duplicated bookmark without "Copy" in its 
name.
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), nActual);
 }
 
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx 
b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 51c0fdb9cba9..d7896c6c113d 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -232,7 +232,7 @@ namespace
 namespace sw
 {
     // TODO: use SaveBookmark (from DelBookmarks)
-    void CopyBookmarks(const SwPaM& rPam, const SwPosition& rCpyPam, 
SwCopyFlags eFlags)
+    void CopyBookmarks(const SwPaM& rPam, const SwPosition& rCpyPam)
     {
         const SwDoc& rSrcDoc = rPam.GetDoc();
         SwDoc& rDestDoc =  rCpyPam.GetDoc();
@@ -283,7 +283,6 @@ namespace sw
         // We have to count the "non-copied" nodes...
         SwNodeOffset nDelCount;
         SwNodeIndex aCorrIdx(InitDelCount(rPam, nDelCount));
-        auto bSkipBookmarks = static_cast<bool>(eFlags & 
SwCopyFlags::SkipBookmarks);
         for(const sw::mark::IMark* const pMark : vMarksToCopy)
         {
             SwPaM aTmpPam(*pCpyStt);
@@ -296,17 +295,10 @@ namespace sw
                 lcl_SetCpyPos(pMark->GetOtherMarkPos(), rStt, *pCpyStt, 
*aTmpPam.GetMark(), nDelCount);
             }
 
-            IDocumentMarkAccess::MarkType eType = 
IDocumentMarkAccess::GetType(*pMark);
-            if (bSkipBookmarks && eType == 
IDocumentMarkAccess::MarkType::BOOKMARK)
-            {
-                // It was requested to skip bookmarks while copying. Do that, 
but continue to copy
-                // other kind of marks, like fieldmarks.
-                continue;
-            }
             ::sw::mark::IMark* const pNewMark = 
rDestDoc.getIDocumentMarkAccess()->makeMark(
                 aTmpPam,
                 pMark->GetName(),
-                eType,
+                IDocumentMarkAccess::GetType(*pMark),
                 ::sw::mark::InsertMode::CopyText);
             // Explicitly try to get exactly the same name as in the source
             // because NavigatorReminders, DdeBookmarks etc. ignore the 
proposed name
@@ -3676,7 +3668,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
             targetPos = pCopiedPaM->second;
         }
 
-        sw::CopyBookmarks(pCopiedPaM ? pCopiedPaM->first : aRgTmp, targetPos, 
flags);
+        sw::CopyBookmarks(pCopiedPaM ? pCopiedPaM->first : aRgTmp, targetPos);
     }
 
     if (rRg.aStart != rRg.aEnd)
@@ -5299,7 +5291,7 @@ bool 
DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo
     // Also copy all bookmarks
     if( bCopyBookmarks && m_rDoc.getIDocumentMarkAccess()->getAllMarksCount() )
     {
-        sw::CopyBookmarks(rPam, *pCopyPam->Start(), SwCopyFlags::Default);
+        sw::CopyBookmarks(rPam, *pCopyPam->Start());
     }
 
     if( RedlineFlags::DeleteRedlines & eOld )
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 76a684282e7c..d38542922b52 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -48,6 +48,7 @@
 #include <libxml/xmlstring.h>
 #include <libxml/xmlwriter.h>
 #include <comphelper/lok.hxx>
+#include <strings.hrc>
 
 constexpr OUStringLiteral S_ANNOTATION_BOOKMARK = u"____";
 
@@ -1717,9 +1718,10 @@ namespace sw::mark
         sal_Int32 nCnt = 1;
         MarkBasenameMapUniqueOffset_t::const_iterator aIter = 
m_aMarkBasenameMapUniqueOffset.find(rName);
         if(aIter != m_aMarkBasenameMapUniqueOffset.end()) nCnt = aIter->second;
+        OUString aPrefix = SwResId(STR_MARK_COPY).replaceFirst("%1", rName);
         while(nCnt < SAL_MAX_INT32)
         {
-            sTmp = rName + OUString::number(nCnt);
+            sTmp = aPrefix + OUString::number(nCnt);
             nCnt++;
             if (lcl_FindMarkByName(sTmp, m_vAllMarks.begin(), 
m_vAllMarks.end()) == m_vAllMarks.end())
             {
diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx
index a5642f053b7c..d75caf8cac0b 100644
--- a/sw/source/core/doc/docdesc.cxx
+++ b/sw/source/core/doc/docdesc.cxx
@@ -302,7 +302,7 @@ void SwDoc::CopyMasterHeader(const SwPageDesc &rChged, 
const SwFormatHeader &rHe
                     
GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRange, nullptr, 
*pSttNd);
                     SwPaM const source(aRange.aStart, aRange.aEnd);
                     SwPosition dest(*pSttNd);
-                    sw::CopyBookmarks(source, dest, SwCopyFlags::Default);
+                    sw::CopyBookmarks(source, dest);
                     pFormat->SetFormatAttr( SwFormatContent( pSttNd ) );
                     rDescFrameFormat.SetFormatAttr( SwFormatHeader( pFormat ) 
);
                 }
@@ -379,7 +379,7 @@ void SwDoc::CopyMasterFooter(const SwPageDesc &rChged, 
const SwFormatFooter &rFo
                     
GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRange, nullptr, 
*pSttNd);
                     SwPaM const source(aRange.aStart, aRange.aEnd);
                     SwPosition dest(*pSttNd);
-                    sw::CopyBookmarks(source, dest, SwCopyFlags::Default);
+                    sw::CopyBookmarks(source, dest);
                     pFormat->SetFormatAttr( SwFormatContent( pSttNd ) );
                     rDescFrameFormat.SetFormatAttr( SwFormatFooter( pFormat ) 
);
                 }
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index ff8d5b0100f7..d9eef9557cb4 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -1406,7 +1406,7 @@ void SwDoc::CopyPageDescHeaderFooterImpl( bool bCpyHeader,
             // TODO: investigate calling CopyWithFlyInFly?
             SwPaM const source(aRg.aStart, aRg.aEnd);
             SwPosition dest(*pSttNd);
-            sw::CopyBookmarks(source, dest, SwCopyFlags::Default);
+            sw::CopyBookmarks(source, dest);
             pNewFormat->SetFormatAttr( SwFormatContent( pSttNd ));
         }
         else
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx 
b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index d2b61500c8c6..49473930f7fe 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -182,7 +182,7 @@ private:
 };
 
 
-void CopyBookmarks(const SwPaM& rPam, const SwPosition& rTarget, SwCopyFlags 
eFlags);
+void CopyBookmarks(const SwPaM& rPam, const SwPosition& rTarget);
 
 void CalcBreaks(std::vector<std::pair<SwNodeOffset, sal_Int32>> & rBreaks,
         SwPaM const & rPam, bool const isOnlyFieldmarks = false);
diff --git a/sw/source/core/unocore/unotext.cxx 
b/sw/source/core/unocore/unotext.cxx
index 9378016997a6..be1f76fe5353 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -86,7 +86,6 @@ public:
     const CursorType            m_eType;
     SwDoc *                     m_pDoc;
     bool                        m_bIsValid;
-    bool m_bCopySkipsBookmarks;
 
     Impl(   SwXText & rThis,
             SwDoc *const pDoc, const CursorType eType)
@@ -95,7 +94,6 @@ public:
         , m_eType(eType)
         , m_pDoc(pDoc)
         , m_bIsValid(nullptr != pDoc)
-        , m_bCopySkipsBookmarks(false)
     {
     }
 
@@ -1123,18 +1121,9 @@ SwXText::getPropertySetInfo()
 }
 
 void SAL_CALL
-SwXText::setPropertyValue(const OUString& aPropertyName,
-        const uno::Any& aValue)
+SwXText::setPropertyValue(const OUString& /*aPropertyName*/,
+        const uno::Any& /*aValue*/)
 {
-    if (aPropertyName == "CopySkipsBookmarks")
-    {
-        bool bValue{};
-        if (aValue >>= bValue)
-        {
-            m_pImpl->m_bCopySkipsBookmarks = bValue;
-        }
-        return;
-    }
     throw lang::IllegalArgumentException();
 }
 
@@ -2413,12 +2402,7 @@ SwXText::copyText(
             // Explicitly request copy text mode, so
             // sw::DocumentContentOperationsManager::CopyFlyInFlyImpl() will 
copy shapes anchored to
             // us, even if we have only a single paragraph.
-            SwCopyFlags eFlags = SwCopyFlags::CheckPosInFly;
-            if (m_pImpl->m_bCopySkipsBookmarks)
-            {
-                eFlags |= SwCopyFlags::SkipBookmarks;
-            }
-            m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, 
rPos, eFlags);
+            m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, 
rPos, SwCopyFlags::CheckPosInFly);
         }
         if (!pFirstNode)
         {   // the node at rPos was split; get rid of the first empty one so
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx 
b/writerfilter/source/dmapper/PropertyMap.cxx
index e848a5780ebf..eec9b678a209 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -874,18 +874,7 @@ void SectionPropertyMap::CopyHeaderFooterTextProperty( 
const uno::Reference< bea
         if ( xPrevStyle.is() )
             xPrevTxt.set( xPrevStyle->getPropertyValue( sName ), 
uno::UNO_QUERY_THROW );
 
-        uno::Reference<beans::XPropertySet> xTxtProps(xTxt, uno::UNO_QUERY);
-        if (xTxtProps.is())
-        {
-            // Skip copying bookmarks, so the number of bookmarks in the 
source document and in the
-            // resulting doc model match.
-            xTxtProps->setPropertyValue("CopySkipsBookmarks", uno::Any(true));
-        }
         xTxt->copyText( xPrevTxt );
-        if (xTxtProps.is())
-        {
-            xTxtProps->setPropertyValue("CopySkipsBookmarks", uno::Any(false));
-        }
     }
     catch ( const uno::Exception& )
     {

Reply via email to