summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/IDocumentContentOperations.hxx3
-rw-r--r--sw/qa/core/doc/data/copy-flag-skip-bookmarks.docxbin0 -> 14728 bytes
-rw-r--r--sw/qa/core/doc/doc.cxx16
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx16
-rw-r--r--sw/source/core/doc/docdesc.cxx4
-rw-r--r--sw/source/core/doc/docfmt.cxx2
-rw-r--r--sw/source/core/inc/DocumentContentOperationsManager.hxx2
-rw-r--r--sw/source/core/unocore/unotext.cxx22
-rw-r--r--writerfilter/source/dmapper/PropertyMap.cxx11
9 files changed, 64 insertions, 12 deletions
diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index 5a95d0ba95b8..60d45d47a0a3 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -75,11 +75,12 @@ 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, 0x07> {};
+ template<> struct typed_flags<SwCopyFlags> : is_typed_flags<SwCopyFlags, 0x0f> {};
}
enum class SwDeleteFlags
diff --git a/sw/qa/core/doc/data/copy-flag-skip-bookmarks.docx b/sw/qa/core/doc/data/copy-flag-skip-bookmarks.docx
new file mode 100644
index 000000000000..3fb27b430a17
--- /dev/null
+++ b/sw/qa/core/doc/data/copy-flag-skip-bookmarks.docx
Binary files differ
diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx
index 87bfd2697621..2ee2ee342bd3 100644
--- a/sw/qa/core/doc/doc.cxx
+++ b/sw/qa/core/doc/doc.cxx
@@ -255,6 +255,22 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testContentControlDelete)
CPPUNIT_ASSERT_EQUAL(OUString("\x0001test\x0001"), pTextNode->GetText());
}
+CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testCopyFlagSkipBookmarks)
+{
+ // 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:
+ // 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.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), nActual);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index c642cde1c8c7..62c362eba181 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)
+ void CopyBookmarks(const SwPaM& rPam, const SwPosition& rCpyPam, SwCopyFlags eFlags)
{
const SwDoc& rSrcDoc = rPam.GetDoc();
SwDoc& rDestDoc = rCpyPam.GetDoc();
@@ -283,6 +283,7 @@ 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);
@@ -295,10 +296,17 @@ 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(),
- IDocumentMarkAccess::GetType(*pMark),
+ eType,
::sw::mark::InsertMode::CopyText);
// Explicitly try to get exactly the same name as in the source
// because NavigatorReminders, DdeBookmarks etc. ignore the proposed name
@@ -3672,7 +3680,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
targetPos = pCopiedPaM->second;
}
- sw::CopyBookmarks(pCopiedPaM ? pCopiedPaM->first : aRgTmp, targetPos);
+ sw::CopyBookmarks(pCopiedPaM ? pCopiedPaM->first : aRgTmp, targetPos, flags);
}
if (rRg.aStart != rRg.aEnd)
@@ -5301,7 +5309,7 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo
// Also copy all bookmarks
if( bCopyBookmarks && m_rDoc.getIDocumentMarkAccess()->getAllMarksCount() )
{
- sw::CopyBookmarks(rPam, *pCopyPam->Start());
+ sw::CopyBookmarks(rPam, *pCopyPam->Start(), SwCopyFlags::Default);
}
if( RedlineFlags::DeleteRedlines & eOld )
diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx
index d75caf8cac0b..a5642f053b7c 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);
+ sw::CopyBookmarks(source, dest, SwCopyFlags::Default);
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);
+ sw::CopyBookmarks(source, dest, SwCopyFlags::Default);
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 357ca66aeb8d..51c0e935e7b2 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);
+ sw::CopyBookmarks(source, dest, SwCopyFlags::Default);
pNewFormat->SetFormatAttr( SwFormatContent( pSttNd ));
}
else
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index 49473930f7fe..d2b61500c8c6 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);
+void CopyBookmarks(const SwPaM& rPam, const SwPosition& rTarget, SwCopyFlags eFlags);
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 c68a1a331c90..5d65f5ef8b63 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -86,6 +86,7 @@ public:
const CursorType m_eType;
SwDoc * m_pDoc;
bool m_bIsValid;
+ bool m_bCopySkipsBookmarks;
Impl( SwXText & rThis,
SwDoc *const pDoc, const CursorType eType)
@@ -94,6 +95,7 @@ public:
, m_eType(eType)
, m_pDoc(pDoc)
, m_bIsValid(nullptr != pDoc)
+ , m_bCopySkipsBookmarks(false)
{
}
@@ -1121,9 +1123,18 @@ 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();
}
@@ -2402,7 +2413,12 @@ 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.
- m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, SwCopyFlags::CheckPosInFly);
+ SwCopyFlags eFlags = SwCopyFlags::CheckPosInFly;
+ if (m_pImpl->m_bCopySkipsBookmarks)
+ {
+ eFlags |= SwCopyFlags::SkipBookmarks;
+ }
+ m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, eFlags);
}
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 eec9b678a209..e848a5780ebf 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -874,7 +874,18 @@ 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& )
{