tdf#130318 - Use the actual cursor position to create ToC "for chapter"
Use the actual cursor position to create ToC "for chapter" beginning at
the current level.
Change-Id: I92e7c440005d52c517efa7e64a61c58da9db3197
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125727
Tested-by: Jenkins
Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index 91fbbc0..828742c 100644
--- a/sw/source/core/doc/doctxm.cxx
+++ b/sw/source/core/doc/doctxm.cxx
@@ -737,6 +737,87 @@ static const SwTextNode* lcl_FindChapterNode( const SwNode& rNd,
return pNd ? pNd->FindOutlineNodeOfLevel(nLvl, pLayout) : nullptr;
}
static bool IsHeadingContained(const SwTextNode* pChptrNd, const SwNode& rNd)
{
const SwNode* pNd = &rNd;
const SwOutlineNodes& rONds = pNd->GetNodes().GetOutLineNds();
bool bIsHeadingContained = false;
if (!rONds.empty())
{
bool bCheckFirst = false;
SwOutlineNodes::size_type nPos;
if (!rONds.Seek_Entry(const_cast<SwNode*>(pNd), &nPos))
{
if (nPos == 0)
bCheckFirst = true;
else
nPos--;
}
if (bCheckFirst)
{
const SwContentNode* pCNd = pNd->GetContentNode();
Point aPt(0, 0);
std::pair<Point, bool> const tmp(aPt, false);
const SwFrame* pChptrFrame = pChptrNd->getLayoutFrame(
pChptrNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp);
const SwPageFrame* pChptrPgFrame = pChptrFrame ? pChptrFrame->FindPageFrame() : nullptr;
const SwFrame* pNdFrame
= pCNd ? pCNd->getLayoutFrame(
pCNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp)
: nullptr;
// Check if the one asking doesn't precede the page of the specified chapter note
bIsHeadingContained
= pNdFrame && pChptrPgFrame
&& pChptrPgFrame->getFrameArea().Top() <= pNdFrame->getFrameArea().Top();
// Check if the one asking doesn't succeed the specified chapter note
if (bIsHeadingContained)
{
const SwNode* aChptrNd = pChptrNd;
if (!rONds.Seek_Entry(const_cast<SwNode*>(aChptrNd), &nPos) && nPos)
nPos--;
// Search for the next outline node with a larger level than the specified chapter node
while (nPos < rONds.size() - 1
&& pChptrNd->GetAttrOutlineLevel()
< rONds[nPos + 1]->GetTextNode()->GetAttrOutlineLevel())
nPos++;
// If there exists such an outline node, check if the one asking doesn't succeed
// the specified chapter node
if (nPos < rONds.size() - 1) {
nPos++;
const auto aONdsTxtNd = rONds[nPos]->GetTextNode();
pChptrFrame = aONdsTxtNd->getLayoutFrame(
aONdsTxtNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr,
&tmp);
pChptrPgFrame = pChptrFrame ? pChptrFrame->FindPageFrame() : nullptr;
bIsHeadingContained
= pNdFrame && pChptrPgFrame
&& pChptrPgFrame->getFrameArea().Top() >= pNdFrame->getFrameArea().Top();
}
}
}
else
{
// Search for the next outline node which lies not within the current chapter node
while (pChptrNd->GetAttrOutlineLevel()
< rONds[nPos]->GetTextNode()->GetAttrOutlineLevel())
nPos--;
bIsHeadingContained = pChptrNd == rONds[nPos]->GetTextNode();
}
}
else
{
// If there are no outline nodes, consider the heading contained,
// otherwise the _XDocumentIndex._update() test fails
bIsHeadingContained = true;
}
return bIsHeadingContained;
}
// Table of contents class
SwTOXBaseSection::SwTOXBaseSection(SwTOXBase const& rBase, SwSectionFormat & rFormat)
: SwTOXBase( rBase )
@@ -855,8 +936,8 @@ void SwTOXBaseSection::Update(const SfxItemSet* pAttr,
// find the first layout node for this TOX, if it only find the content
// in his own chapter
const SwTextNode* pOwnChapterNode = IsFromChapter()
? ::lcl_FindChapterNode( *pSectNd, pLayout )
: nullptr;
? ::lcl_FindChapterNode( *pSectNd, pLayout, pSectNd->FindSectionNode()->GetSectionLevel() + 1 )
: nullptr;
SwNode2LayoutSaveUpperFrames aN2L(*pSectNd);
const_cast<SwSectionNode*>(pSectNd)->DelFrames();
@@ -1205,7 +1286,7 @@ void SwTOXBaseSection::UpdateMarks(const SwTOXInternational& rIntl,
{
::SetProgressState(0, pShell);
auto& rNode = rMark.get().GetTextNode();
if(IsFromChapter() && ::lcl_FindChapterNode(rNode, pLayout) != pOwnChapterNode)
if(IsFromChapter() && !IsHeadingContained(pOwnChapterNode, rNode))
continue;
auto rTOXMark = rMark.get().GetTOXMark();
if(TOX_INDEX == eTOXTyp)
@@ -1249,8 +1330,7 @@ void SwTOXBaseSection::UpdateOutline( const SwTextNode* pOwnChapterNode,
!pTextNd->HasHiddenCharAttribute( true ) &&
(!pLayout || !pLayout->HasMergedParas()
|| static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout))->GetTextNodeForParaProps() == pTextNd) &&
( !IsFromChapter() ||
::lcl_FindChapterNode(*pTextNd, pLayout) == pOwnChapterNode ))
( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pTextNd) ))
{
InsertSorted(MakeSwTOXSortTabBase<SwTOXPara>(pLayout, *pTextNd, SwTOXElement::OutlineLevel));
}
@@ -1290,8 +1370,7 @@ void SwTOXBaseSection::UpdateTemplate(const SwTextNode* pOwnChapterNode,
pTextNd->GetNodes().IsDocNodes() &&
(!pLayout || !pLayout->HasMergedParas()
|| static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout))->GetTextNodeForParaProps() == pTextNd) &&
(!IsFromChapter() || pOwnChapterNode ==
::lcl_FindChapterNode(*pTextNd, pLayout)))
(!IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pTextNd)))
{
InsertSorted(MakeSwTOXSortTabBase<SwTOXPara>(pLayout, *pTextNd, SwTOXElement::Template, i + 1));
}
@@ -1319,8 +1398,7 @@ void SwTOXBaseSection::UpdateSequence(const SwTextNode* pOwnChapterNode,
if (rTextNode.GetText().getLength() &&
rTextNode.getLayoutFrame(pLayout) &&
( !IsFromChapter() ||
::lcl_FindChapterNode(rTextNode, pLayout) == pOwnChapterNode)
( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, rTextNode))
&& (!pLayout || !pLayout->IsHideRedlines()
|| !sw::IsFieldDeletedInModel(pDoc->getIDocumentRedlineAccess(), *pTextField)))
{
@@ -1513,8 +1591,7 @@ void SwTOXBaseSection::UpdateContent( SwTOXElement eMyType,
if (pCNd->getLayoutFrame(pLayout)
&& (!pLayout || !pLayout->HasMergedParas()
|| pCNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden)
&& ( !IsFromChapter() ||
::lcl_FindChapterNode(*pCNd, pLayout) == pOwnChapterNode ))
&& ( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pCNd)))
{
std::unique_ptr<SwTOXPara> pNew( MakeSwTOXSortTabBase<SwTOXPara>(
pLayout, *pCNd, eMyType,
@@ -1556,8 +1633,7 @@ void SwTOXBaseSection::UpdateTable(const SwTextNode* pOwnChapterNode,
if (pCNd->getLayoutFrame(pLayout)
&& (!pLayout || !pLayout->HasMergedParas()
|| pCNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden)
&& (!IsFromChapter()
|| ::lcl_FindChapterNode(*pCNd, pLayout) == pOwnChapterNode))
&& (!IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pCNd)))
{
std::unique_ptr<SwTOXTable> pNew(new SwTOXTable( *pCNd ));
if( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType())