sw/source/core/doc/doctxm.cxx |  102 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 89 insertions(+), 13 deletions(-)

New commits:
commit 1cac7d18ab8561f129a30d6c93c0f9f1d7868e01
Author:     Andreas Heinisch <andreas.heini...@yahoo.de>
AuthorDate: Tue Nov 23 17:48:37 2021 +0100
Commit:     Ilmari Lauhakangas <ilmari.lauhakan...@libreoffice.org>
CommitDate: Thu Mar 31 16:34:19 2022 +0200

    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.lauhakan...@libreoffice.org>

diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index 91fbbc03fe56..828742c0e37c 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())

Reply via email to