sw/inc/reffld.hxx | 7 sw/source/core/fields/reffld.cxx | 394 ++++++++++++++++++++------------------- 2 files changed, 210 insertions(+), 191 deletions(-)
New commits: commit 285b66443303b8e240a6af48adb1f58bf4f8644e Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Wed Dec 4 15:57:14 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Wed Dec 4 17:06:19 2024 +0100 split up SwGetRefFieldType::FindAnchor method to make it easier to read Change-Id: Ifaece90d4fb18be3caae9fd4afbbbdf64ff9d18a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177800 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/sw/inc/reffld.hxx b/sw/inc/reffld.hxx index a6d51679f101..471226b7f028 100644 --- a/sw/inc/reffld.hxx +++ b/sw/inc/reffld.hxx @@ -101,6 +101,13 @@ public: SwTextNode* pSelf = nullptr, SwFrame* pFrame = nullptr); void UpdateGetReferences(); void UpdateStyleReferences(); + +private: + static SwTextNode* FindAnchorRefStyle( SwDoc* pDoc, const OUString& rRefMark, + sal_uInt16 nFlags, + sal_Int32* pStt, sal_Int32* pEnd, + SwRootFrame const* pLayout, + SwTextNode* pSelf, SwFrame* pFrame); }; class SAL_DLLPUBLIC_RTTI SwGetRefField final : public SwField diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx index e994dabfab17..0a1e25a119a1 100644 --- a/sw/source/core/fields/reffld.cxx +++ b/sw/source/core/fields/reffld.cxx @@ -1390,249 +1390,261 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark, } break; case REF_STYLE: - if (!pSelf) break; + pTextNd = FindAnchorRefStyle(pDoc, rRefMark, nFlags, + pStt, pEnd, pLayout, pSelf, pContentFrame); + break; + } - const SwNodes& nodes = pDoc->GetNodes(); + return pTextNd; +} - StyleRefElementType elementType = StyleRefElementType::Default; - const SwTextNode* pReference = nullptr; +SwTextNode* SwGetRefFieldType::FindAnchorRefStyle(SwDoc* pDoc, const OUString& rRefMark, + sal_uInt16 nFlags, + sal_Int32* pStt, sal_Int32* pEnd, SwRootFrame const* const pLayout, + SwTextNode* pSelf, SwFrame* pContentFrame) +{ + if (!pSelf) + return nullptr; - { /* Check if we're a footnote/endnote */ - for (SwTextFootnote* pFootnoteIdx : pDoc->GetFootnoteIdxs()) - { - if (pLayout && pLayout->IsHideRedlines() - && sw::IsFootnoteDeleted(rIDRA, *pFootnoteIdx)) - { - continue; - } - const SwNodeIndex* pIdx = pFootnoteIdx->GetStartNode(); - if (pIdx) - { - SwNodeIndex aIdx(*pIdx, 1); - SwTextNode* pFootnoteNode = aIdx.GetNode().GetTextNode(); - if (nullptr == pFootnoteNode) - pFootnoteNode = static_cast<SwTextNode*>(SwNodes::GoNext(&aIdx)); + SwTextNode* pTextNd = nullptr; - if (*pSelf == *pFootnoteNode) - { - elementType = StyleRefElementType::Reference; - pReference = &pFootnoteIdx->GetTextNode(); - } - } - } - } + const SwNodes& nodes = pDoc->GetNodes(); - if (pDoc->IsInHeaderFooter(*pSelf)) - { - elementType = StyleRefElementType::Marginal; - } + StyleRefElementType elementType = StyleRefElementType::Default; + const SwTextNode* pReference = nullptr; + IDocumentRedlineAccess & rIDRA(pDoc->getIDocumentRedlineAccess()); + + /* Check if we're a footnote/endnote */ + for (SwTextFootnote* pFootnoteIdx : pDoc->GetFootnoteIdxs()) + { + if (pLayout && pLayout->IsHideRedlines() + && sw::IsFootnoteDeleted(rIDRA, *pFootnoteIdx)) + { + continue; + } + const SwNodeIndex* pIdx = pFootnoteIdx->GetStartNode(); + if (pIdx) + { + SwNodeIndex aIdx(*pIdx, 1); + SwTextNode* pFootnoteNode = aIdx.GetNode().GetTextNode(); + if (nullptr == pFootnoteNode) + pFootnoteNode = static_cast<SwTextNode*>(SwNodes::GoNext(&aIdx)); - if (pReference == nullptr) + if (*pSelf == *pFootnoteNode) { - pReference = pSelf; + elementType = StyleRefElementType::Reference; + pReference = &pFootnoteIdx->GetTextNode(); } + } + } - // undocumented Word feature: 1 = "Heading 1" etc. - OUString const styleName( - (rRefMark.getLength() == 1 && '1' <= rRefMark[0] && rRefMark[0] <= '9') - ? SwStyleNameMapper::GetProgName(RES_POOLCOLL_HEADLINE1 + rRefMark[0] - '1', rRefMark) - : rRefMark); + if (pDoc->IsInHeaderFooter(*pSelf)) + { + elementType = StyleRefElementType::Marginal; + } - switch (elementType) - { - case Marginal: - { - // For marginals, styleref tries to act on the current page first - // 1. Get the page we're on, search it from top to bottom + if (pReference == nullptr) + { + pReference = pSelf; + } - bool bFlagFromBottom = (nFlags & REFFLDFLAG_STYLE_FROM_BOTTOM) == REFFLDFLAG_STYLE_FROM_BOTTOM; + // undocumented Word feature: 1 = "Heading 1" etc. + OUString const styleName( + (rRefMark.getLength() == 1 && '1' <= rRefMark[0] && rRefMark[0] <= '9') + ? SwStyleNameMapper::GetProgName(RES_POOLCOLL_HEADLINE1 + rRefMark[0] - '1', rRefMark) + : rRefMark); - Point aPt; - std::pair<Point, bool> const tmp(aPt, false); + switch (elementType) + { + case Marginal: + { + // For marginals, styleref tries to act on the current page first + // 1. Get the page we're on, search it from top to bottom - if (!pContentFrame) SAL_WARN("xmloff.text", "<SwGetRefFieldType::FindAnchor(..)>: Missing content frame for marginal styleref"); - const SwPageFrame* pPageFrame = nullptr; + bool bFlagFromBottom = (nFlags & REFFLDFLAG_STYLE_FROM_BOTTOM) == REFFLDFLAG_STYLE_FROM_BOTTOM; - if (pContentFrame) - pPageFrame = pContentFrame->FindPageFrame(); + Point aPt; + std::pair<Point, bool> const tmp(aPt, false); - const SwNode* pPageStart(nullptr); - const SwNode* pPageEnd(nullptr); + if (!pContentFrame) SAL_WARN("xmloff.text", "<SwGetRefFieldType::FindAnchor(..)>: Missing content frame for marginal styleref"); + const SwPageFrame* pPageFrame = nullptr; - if (pPageFrame) - { - const SwContentFrame* pPageStartFrame = pPageFrame->FindFirstBodyContent(); - const SwContentFrame* pPageEndFrame = pPageFrame->FindLastBodyContent(); + if (pContentFrame) + pPageFrame = pContentFrame->FindPageFrame(); - if (pPageStartFrame) { - if (pPageStartFrame->IsTextFrame()) - { - pPageStart = static_cast<const SwTextFrame*>(pPageStartFrame) - ->GetTextNodeFirst(); - } - else - { - pPageStart - = static_cast<const SwNoTextFrame*>(pPageStartFrame)->GetNode(); - } - } + const SwNode* pPageStart(nullptr); + const SwNode* pPageEnd(nullptr); - if (pPageEndFrame) { - if (pPageEndFrame->IsTextFrame()) - { - pPageEnd = static_cast<const SwTextFrame*>(pPageEndFrame) - ->GetTextNodeFirst(); - } - else - { - pPageEnd = static_cast<const SwNoTextFrame*>(pPageEndFrame)->GetNode(); - } - } - } + if (pPageFrame) + { + const SwContentFrame* pPageStartFrame = pPageFrame->FindFirstBodyContent(); + const SwContentFrame* pPageEndFrame = pPageFrame->FindLastBodyContent(); - if (!pPageStart || !pPageEnd) + if (pPageStartFrame) { + if (pPageStartFrame->IsTextFrame()) { - pPageStart = pReference; - pPageEnd = pReference; + pPageStart = static_cast<const SwTextFrame*>(pPageStartFrame) + ->GetTextNodeFirst(); } - - std::deque<SwNode*> pSearchSecond; - std::deque<SwNode*> pInPage; /* or pSearchFirst */ - std::deque<SwNode*> pSearchThird; - - bool beforeStart = true; - bool beforeEnd = true; - - for (SwNodeOffset n(0); n < nodes.Count(); n++) + else { - if (beforeStart && *pPageStart == *nodes[n]) - { - beforeStart = false; - } - - if (beforeStart) - { - pSearchSecond.push_front(nodes[n]); - } - else if (beforeEnd) - { - if (bFlagFromBottom) - pInPage.push_front(nodes[n]); - else - pInPage.push_back(nodes[n]); - - if (*pPageEnd == *nodes[n]) - { - beforeEnd = false; - } - } - else - pSearchThird.push_back(nodes[n]); + pPageStart + = static_cast<const SwNoTextFrame*>(pPageStartFrame)->GetNode(); } + } - pTextNd = SearchForStyleAnchor(pSelf, pInPage, styleName, pStt, pEnd); - if (pTextNd) + if (pPageEndFrame) { + if (pPageEndFrame->IsTextFrame()) { - break; + pPageEnd = static_cast<const SwTextFrame*>(pPageEndFrame) + ->GetTextNodeFirst(); } - - // 2. Search up from the top of the page - pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, styleName, pStt, pEnd); - if (pTextNd) + else { - break; + pPageEnd = static_cast<const SwNoTextFrame*>(pPageEndFrame)->GetNode(); } + } + } - // 3. Search down from the bottom of the page - pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, styleName, pStt, pEnd); - if (pTextNd) - { - break; - } + if (!pPageStart || !pPageEnd) + { + pPageStart = pReference; + pPageEnd = pReference; + } - // Word has case insensitive styles. LO has case sensitive styles. If we didn't find - // it yet, maybe we could with a case insensitive search. Let's do that + std::deque<SwNode*> pSearchSecond; + std::deque<SwNode*> pInPage; /* or pSearchFirst */ + std::deque<SwNode*> pSearchThird; - pTextNd = SearchForStyleAnchor(pSelf, pInPage, styleName, pStt, pEnd, - false /* bCaseSensitive */); - if (pTextNd) - { - break; - } + bool beforeStart = true; + bool beforeEnd = true; - pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, styleName, pStt, pEnd, - false /* bCaseSensitive */); - if (pTextNd) - { - break; - } + for (SwNodeOffset n(0); n < nodes.Count(); n++) + { + if (beforeStart && *pPageStart == *nodes[n]) + { + beforeStart = false; + } - pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, styleName, pStt, pEnd, - false /* bCaseSensitive */); - break; + if (beforeStart) + { + pSearchSecond.push_front(nodes[n]); } - case Reference: - case Default: + else if (beforeEnd) { - // Normally, styleref does searches around the field position - // For references, styleref acts from the position of the reference not the field - // Happily, the previous code saves either one into pReference, so the following is generic for both + if (bFlagFromBottom) + pInPage.push_front(nodes[n]); + else + pInPage.push_back(nodes[n]); - std::deque<SwNode*> pSearchFirst; - std::deque<SwNode*> pSearchSecond; + if (*pPageEnd == *nodes[n]) + { + beforeEnd = false; + } + } + else + pSearchThird.push_back(nodes[n]); + } - bool beforeElement = true; + pTextNd = SearchForStyleAnchor(pSelf, pInPage, styleName, pStt, pEnd); + if (pTextNd) + { + break; + } - for (SwNodeOffset n(0); n < nodes.Count(); n++) - { - if (beforeElement) - { - pSearchFirst.push_front(nodes[n]); + // 2. Search up from the top of the page + pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, styleName, pStt, pEnd); + if (pTextNd) + { + break; + } - if (*pReference == *nodes[n]) - { - beforeElement = false; - } - } - pSearchSecond.push_back(nodes[n]); - } + // 3. Search down from the bottom of the page + pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, styleName, pStt, pEnd); + if (pTextNd) + { + break; + } - // 1. Search up until we hit the top of the document + // Word has case insensitive styles. LO has case sensitive styles. If we didn't find + // it yet, maybe we could with a case insensitive search. Let's do that - pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, styleName, pStt, pEnd); - if (pTextNd) - { - break; - } + pTextNd = SearchForStyleAnchor(pSelf, pInPage, styleName, pStt, pEnd, + false /* bCaseSensitive */); + if (pTextNd) + { + break; + } - // 2. Search down until we hit the bottom of the document + pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, styleName, pStt, pEnd, + false /* bCaseSensitive */); + if (pTextNd) + { + break; + } - pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, styleName, pStt, pEnd); - if (pTextNd) - { - break; - } + pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, styleName, pStt, pEnd, + false /* bCaseSensitive */); + break; + } + case Reference: + case Default: + { + // Normally, styleref does searches around the field position + // For references, styleref acts from the position of the reference not the field + // Happily, the previous code saves either one into pReference, so the following is generic for both + + std::deque<SwNode*> pSearchFirst; + std::deque<SwNode*> pSearchSecond; - // Again, we need to remember that Word styles are not case sensitive + bool beforeElement = true; - pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, styleName, pStt, pEnd, - false /* bCaseSensitive */); - if (pTextNd) + for (SwNodeOffset n(0); n < nodes.Count(); n++) + { + if (beforeElement) + { + pSearchFirst.push_front(nodes[n]); + + if (*pReference == *nodes[n]) { - break; + beforeElement = false; } - - pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, styleName, pStt, pEnd, - false /* bCaseSensitive */); - break; } - default: - OSL_FAIL("<SwGetRefFieldType::FindAnchor(..)> - unknown getref element type"); + pSearchSecond.push_back(nodes[n]); + } + + // 1. Search up until we hit the top of the document + + pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, styleName, pStt, pEnd); + if (pTextNd) + { + break; + } + + // 2. Search down until we hit the bottom of the document + + pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, styleName, pStt, pEnd); + if (pTextNd) + { + break; } + // Again, we need to remember that Word styles are not case sensitive + + pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, styleName, pStt, pEnd, + false /* bCaseSensitive */); + if (pTextNd) + { + break; + } + + pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, styleName, pStt, pEnd, + false /* bCaseSensitive */); break; + } + default: + OSL_FAIL("<SwGetRefFieldType::FindAnchor(..)> - unknown getref element type"); } - return pTextNd; }