diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2019-11-21 13:38:38 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@cib.de> | 2019-11-21 19:01:50 +0100 |
commit | ab90d83d73b701747a56e09f71e3609a92378504 (patch) | |
tree | a33f11fe0d676c888bbb1a39df765a8198222f24 | |
parent | 844b4ac41009143092ef08f163783d48dfbe9b77 (diff) |
sw: check fieldmark overlap in SwpHints::TryInsertNesting()
This is a follow-up to bd2ada701aad2c4e85d03cd8db68eaeae081d91c,
which added the check for nesting hints in MarkManager::makeMark().
Change-Id: Ife847a677514fb1aeb28dc8d6254caea365b754d
Reviewed-on: https://gerrit.libreoffice.org/83388
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 18 | ||||
-rw-r--r-- | sw/source/core/inc/DocumentContentOperationsManager.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/txtnode/thints.cxx | 48 |
3 files changed, 56 insertions, 13 deletions
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 3b9433619ae6..731bac5b7b49 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -484,10 +484,10 @@ namespace } //local functions originally from sw/source/core/doc/docedt.cxx -namespace +namespace sw { - void - lcl_CalcBreaks(std::vector<std::pair<sal_uLong, sal_Int32>> & rBreaks, SwPaM const & rPam, bool const isOnlyFieldmarks = false) + void CalcBreaks(std::vector<std::pair<sal_uLong, sal_Int32>> & rBreaks, + SwPaM const & rPam, bool const isOnlyFieldmarks) { sal_uLong const nStartNode(rPam.Start()->nNode.GetIndex()); sal_uLong const nEndNode(rPam.End()->nNode.GetIndex()); @@ -589,13 +589,17 @@ namespace rBreaks.insert(it, pos); } } +} + +namespace +{ bool lcl_DoWithBreaks(::sw::DocumentContentOperationsManager & rDocumentContentOperations, SwPaM & rPam, bool (::sw::DocumentContentOperationsManager::*pFunc)(SwPaM&, bool), const bool bForceJoinNext = false) { std::vector<std::pair<sal_uLong, sal_Int32>> Breaks; - lcl_CalcBreaks(Breaks, rPam); + sw::CalcBreaks(Breaks, rPam); if (Breaks.empty()) { @@ -1802,7 +1806,7 @@ namespace mark bool IsFieldmarkOverlap(SwPaM const& rPaM) { std::vector<std::pair<sal_uLong, sal_Int32>> Breaks; - lcl_CalcBreaks(Breaks, rPaM); + sw::CalcBreaks(Breaks, rPaM); return !Breaks.empty(); } } @@ -3181,7 +3185,7 @@ bool DocumentContentOperationsManager::ReplaceRange( SwPaM& rPam, const OUString } OSL_ENSURE((aPam.GetPoint()->nNode == aPam.GetMark()->nNode), "invalid pam?"); - lcl_CalcBreaks(Breaks, aPam); + sw::CalcBreaks(Breaks, aPam); while (!Breaks.empty() // skip over prefix of dummy chars && (aPam.GetMark()->nNode.GetIndex() == Breaks.begin()->first) @@ -4444,7 +4448,7 @@ bool DocumentContentOperationsManager::CopyImpl(SwPaM& rPam, SwPosition& rPos, { std::vector<std::pair<sal_uLong, sal_Int32>> Breaks; - lcl_CalcBreaks(Breaks, rPam, true); + sw::CalcBreaks(Breaks, rPam, true); if (Breaks.empty()) { diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx index bf765d291d46..21829eaf22a5 100644 --- a/sw/source/core/inc/DocumentContentOperationsManager.hxx +++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx @@ -180,6 +180,9 @@ private: void CopyBookmarks(const SwPaM& rPam, SwPosition& rTarget); +void CalcBreaks(std::vector<std::pair<sal_uLong, sal_Int32>> & rBreaks, + SwPaM const & rPam, bool const isOnlyFieldmarks = false); + } #endif // INCLUDED_SW_SOURCE_CORE_INC_DOCUMENTCONTENTOPERATIONSMANAGER_HXX diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 0005d65e276a..35819fa8214d 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -21,6 +21,7 @@ #include <sal/log.hxx> #include <DocumentSettingManager.hxx> +#include <DocumentContentOperationsManager.hxx> #include <hintids.hxx> #include <editeng/xmlcnitm.hxx> #include <editeng/rsiditem.hxx> @@ -259,6 +260,19 @@ MakeTextAttrNesting(SwTextNode & rNode, SwTextAttrNesting & rNesting, typedef std::vector<SwTextAttrNesting *> NestList_t; +static NestList_t::iterator +lcl_DoSplitImpl(NestList_t & rSplits, SwTextNode & rNode, + NestList_t::iterator const iter, sal_Int32 const nSplitPos, + bool const bSplitAtStart, bool const bOtherDummy) +{ + const sal_Int32 nStartPos( // skip other's dummy character! + (bSplitAtStart && bOtherDummy) ? nSplitPos + 1 : nSplitPos ); + SwTextAttrNesting * const pNew( MakeTextAttrNesting( + rNode, **iter, nStartPos, *(*iter)->GetEnd() ) ); + (*iter)->SetEnd(nSplitPos); + return rSplits.insert(iter + 1, pNew); +} + static void lcl_DoSplitNew(NestList_t & rSplits, SwTextNode & rNode, const sal_Int32 nNewStart, @@ -274,12 +288,7 @@ lcl_DoSplitNew(NestList_t & rSplits, SwTextNode & rNode, } ) ); if (iter != rSplits.end()) // already split here? { - const sal_Int32 nStartPos( // skip other's dummy character! - (bSplitAtStart && bOtherDummy) ? nSplitPos + 1 : nSplitPos ); - SwTextAttrNesting * const pNew( MakeTextAttrNesting( - rNode, **iter, nStartPos, *(*iter)->GetEnd() ) ); - (*iter)->SetEnd(nSplitPos); - rSplits.insert(iter + 1, pNew); + lcl_DoSplitImpl(rSplits, rNode, iter, nSplitPos, bSplitAtStart, bOtherDummy); } } @@ -441,6 +450,33 @@ SwpHints::TryInsertNesting( SwTextNode & rNode, SwTextAttrNesting & rNewHint ) } } + // pass 1b: tragically need to check for fieldmarks here too + for (auto iter = SplitNew.begin(); iter != SplitNew.end(); ++iter) + { + SwPaM const temp(rNode, (*iter)->GetStart(), rNode, *(*iter)->GetEnd()); + std::vector<std::pair<sal_uLong, sal_Int32>> Breaks; + sw::CalcBreaks(Breaks, temp, true); + if (!Breaks.empty()) + { + if (!isSplittable(nNewWhich)) + { + SAL_INFO("sw.core", "cannot insert hint: fieldmark overlap"); + assert(SplitNew.size() == 1); + TextAttrDelete(*rNode.GetDoc(), &rNewHint); + return false; + } + else + { + for (auto const& rPos : Breaks) + { + assert(rPos.first == rNode.GetIndex()); + iter = lcl_DoSplitImpl(SplitNew, rNode, iter, + rPos.second, true, true); + } + } + } + } + assert((isSplittable(nNewWhich) || SplitNew.size() == 1) && "splitting the unsplittable ???"); |