sw/qa/extras/uiwriter/data/IndexElementsInHiddenSections.fodt |   63 +++++++
 sw/qa/extras/uiwriter/uiwriter9.cxx                           |   43 +++++
 sw/source/core/doc/doctxm.cxx                                 |   79 ++++++----
 sw/source/core/tox/tox.cxx                                    |    3 
 4 files changed, 158 insertions(+), 30 deletions(-)

New commits:
commit a5edc358b158ec017f26ab83ca42e0af31ce0147
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sat Nov 23 11:02:07 2024 +0500
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Nov 25 10:25:02 2024 +0100

    tdf#162195: use SwFrame::IsHiddenNow when building index
    
    Before commit 0c96119895b347f8eb5bb89f393351bd3c02b9f1 (tdf#159565
    prerequisite: make hidden sections have zero-height frames, 2024-02-15),
    the hidden sections were absent from layout, so didn't appear in the
    SwTOXBaseSection::Update* functions. Now they are zero-height, but
    present, so their visibility must be taken into account explicitly.
    
    Change-Id: I95cc72b383a99e1f65152579c5458e253a3f60ea
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177079
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177102
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/uiwriter/data/IndexElementsInHiddenSections.fodt 
b/sw/qa/extras/uiwriter/data/IndexElementsInHiddenSections.fodt
new file mode 100644
index 000000000000..5fb3d809404f
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/IndexElementsInHiddenSections.fodt
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+  <style:style style:name="CustomTOCStyle" style:family="paragraph" 
style:class="text"/>
+ </office:styles>
+ <office:body>
+  <office:text>
+   <text:table-of-content>
+    <text:table-of-content-source text:outline-level="1" 
text:use-index-source-styles="true">
+     <text:index-title-template text:style-name="Contents_20_Heading">Table of 
Contents</text:index-title-template>
+     <text:table-of-content-entry-template text:outline-level="1" 
text:style-name="Contents_20_1">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:index-source-styles text:outline-level="1">
+      <text:index-source-style text:style-name="CustomTOCStyle"/>
+     </text:index-source-styles>
+    </text:table-of-content-source>
+   </text:table-of-content>
+   <text:section text:name="Section Visible">
+    <text:h text:outline-level="1">Section Visible</text:h>
+    <text:p>foo</text:p>
+    <table:table table:name="Table1">
+     <table:table-column/>
+     <table:table-row>
+      <table:table-cell/>
+     </table:table-row>
+    </table:table>
+   </text:section>
+   <text:section text:name="Section Hidden" text:display="none">
+    <text:h text:outline-level="1">Section Hidden</text:h>
+    <text:p>bar</text:p>
+    <text:p/>
+    <text:p>A level-1 <text:toc-mark-start text:id="IMark1" 
text:outline-level="1"/>entry<text:toc-mark-end text:id="IMark1"/></text:p>
+    <text:p/>
+    <text:p text:style-name="CustomTOCStyle">CustomTOCStyle paragraph</text:p>
+    <table:table table:name="Table2">
+     <table:table-column/>
+     <table:table-row>
+      <table:table-cell/>
+     </table:table-row>
+    </table:table>
+   </text:section>
+   <text:table-index>
+    <text:table-index-source text:use-caption="false" 
text:caption-sequence-name="Table" text:caption-sequence-format="text">
+     <text:index-title-template 
text:style-name="Table_20_index_20_heading">Index of 
Tables</text:index-title-template>
+     <text:table-index-entry-template text:style-name="Table_20_index_20_1">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-index-entry-template>
+    </text:table-index-source>
+   </text:table-index>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index 8523bd95c9eb..2f8d9b68ba2f 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -677,6 +677,49 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf144752)
     CPPUNIT_ASSERT_EQUAL(u"Word"_ustr, pWrtShell->GetSelText());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162195)
+{
+    // Given a document, which has some index entries in a hidden section
+    createSwDoc("IndexElementsInHiddenSections.fodt");
+
+    auto 
xIndexSupplier(mxComponent.queryThrow<css::text::XDocumentIndexesSupplier>());
+    auto xIndexes = xIndexSupplier->getDocumentIndexes();
+    CPPUNIT_ASSERT(xIndexes);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexes->getCount()); // A ToC and a 
table index
+
+    auto xToC(xIndexes->getByIndex(0).queryThrow<css::text::XDocumentIndex>());
+    xToC->update();
+    // Without the fix, all the elements from the hidden section appeared in 
the index
+    CPPUNIT_ASSERT_EQUAL(u"Table of Contents" SAL_NEWLINE_STRING "Section 
Visible      1"_ustr,
+                         xToC->getAnchor()->getString());
+
+    auto 
xTables(xIndexes->getByIndex(1).queryThrow<css::text::XDocumentIndex>());
+    xTables->update();
+    // Without the fix, all the elements from the hidden section appeared in 
the index
+    CPPUNIT_ASSERT_EQUAL(u"Index of Tables" SAL_NEWLINE_STRING "Table1 1"_ustr,
+                         xTables->getAnchor()->getString());
+
+    // Show the hidden section
+    auto xTextSectionsSupplier = 
mxComponent.queryThrow<css::text::XTextSectionsSupplier>();
+    auto xSections = xTextSectionsSupplier->getTextSections();
+    CPPUNIT_ASSERT(xSections);
+    auto xSection
+        = xSections->getByName(u"Section 
Hidden"_ustr).queryThrow<css::beans::XPropertySet>();
+    xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
+
+    xToC->update();
+    CPPUNIT_ASSERT_EQUAL(u"Table of Contents" SAL_NEWLINE_STRING
+                         "Section Visible      1" SAL_NEWLINE_STRING
+                         "Section Hidden       1" SAL_NEWLINE_STRING "entry    
1" SAL_NEWLINE_STRING
+                         "CustomTOCStyle paragraph     1"_ustr,
+                         xToC->getAnchor()->getString());
+
+    xTables->update();
+    CPPUNIT_ASSERT_EQUAL(u"Index of Tables" SAL_NEWLINE_STRING "Table1 1" 
SAL_NEWLINE_STRING
+                         "Table2       1"_ustr,
+                         xTables->getAnchor()->getString());
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index 4463bdc7c29b..2c82418d5c96 100644
--- a/sw/source/core/doc/doctxm.cxx
+++ b/sw/source/core/doc/doctxm.cxx
@@ -1350,6 +1350,48 @@ void SwTOXBaseSection::UpdateMarks(const 
SwTOXInternational& rIntl,
     }
 }
 
+static SwContentFrame* useContentNodeForIndex(const SwContentNode* node, bool 
fromChapter,
+                                              const SwTextNode* chapter, const 
SwRootFrame* layout)
+{
+    if (!node)
+        return nullptr;
+    if (!node->HasWriterListeners())
+        return nullptr;
+    if (!node->GetNodes().IsDocNodes())
+        return nullptr;
+    if (layout && layout->HasMergedParas() && node->GetRedlineMergeFlag() == 
SwNode::Merge::Hidden)
+        return nullptr;
+    auto pFrame = node->getLayoutFrame(layout);
+    if (!pFrame)
+        return nullptr;
+    if (fromChapter && !IsHeadingContained(chapter, *node))
+        return nullptr;
+    if (pFrame->IsHiddenNow())
+        return nullptr;
+
+    return pFrame;
+}
+
+static bool useTextNodeForIndex(const SwTextNode* node, int maxLevel, bool 
fromChapter,
+                                const SwTextNode* chapter, const SwRootFrame* 
layout)
+{
+    auto pTextFrame = static_cast<const 
SwTextFrame*>(useContentNodeForIndex(node, fromChapter, chapter, layout));
+    if (!pTextFrame)
+        return false;
+    if (node->Len() == 0)
+        return false;
+    if (maxLevel >= 0 && node->GetAttrOutlineLevel() > maxLevel)
+        return false;
+    if (node->IsHiddenByParaField())
+        return false;
+    if (node->HasHiddenCharAttribute(true))
+        return false;
+    if (layout && layout->HasMergedParas() && 
pTextFrame->GetTextNodeForParaProps() != node)
+        return false;
+
+    return true;
+}
+
 /// Generate table of contents from outline
 void SwTOXBaseSection::UpdateOutline( const SwTextNode* pOwnChapterNode,
         SwRootFrame const*const pLayout)
@@ -1362,14 +1404,7 @@ void SwTOXBaseSection::UpdateOutline( const SwTextNode* 
pOwnChapterNode,
     {
         ::SetProgressState( 0, pDoc->GetDocShell() );
         SwTextNode* pTextNd = pOutlineNode->GetTextNode();
-        if( pTextNd && pTextNd->Len() && pTextNd->HasWriterListeners() &&
-            o3tl::make_unsigned( pTextNd->GetAttrOutlineLevel()) <= GetLevel() 
&&
-            pTextNd->getLayoutFrame(pLayout) &&
-           !pTextNd->IsHiddenByParaField() &&
-           !pTextNd->HasHiddenCharAttribute( true ) &&
-           (!pLayout || !pLayout->HasMergedParas()
-                || 
static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout))->GetTextNodeForParaProps()
 == pTextNd) &&
-            ( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, 
*pTextNd) ))
+        if (useTextNodeForIndex(pTextNd, GetLevel(), IsFromChapter(), 
pOwnChapterNode, pLayout))
         {
             InsertSorted(MakeSwTOXSortTabBase<SwTOXPara>(pLayout, *pTextNd, 
SwTOXElement::OutlineLevel));
         }
@@ -1380,6 +1415,7 @@ void SwTOXBaseSection::UpdateOutline( const SwTextNode* 
pOwnChapterNode,
 void SwTOXBaseSection::UpdateTemplate(const SwTextNode* pOwnChapterNode,
         SwRootFrame const*const pLayout)
 {
+    int nMaxLevel = SwTOXBase::GetType() == TOX_CONTENT ? GetLevel() : -1;
     SwDoc* pDoc = GetFormat()->GetDoc();
     for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
     {
@@ -1404,15 +1440,7 @@ void SwTOXBaseSection::UpdateTemplate(const SwTextNode* 
pOwnChapterNode,
             {
                 ::SetProgressState( 0, pDoc->GetDocShell() );
 
-                if (pTextNd->GetText().getLength() &&
-                    pTextNd->getLayoutFrame(pLayout) &&
-                    pTextNd->GetNodes().IsDocNodes() &&
-                    // tdf#40142 - consider level settings of the various text 
nodes
-                    (TOX_CONTENT != SwTOXBase::GetType() ||
-                     o3tl::make_unsigned(pTextNd->GetAttrOutlineLevel()) <= 
GetLevel()) &&
-                    (!pLayout || !pLayout->HasMergedParas()
-                        || 
static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout))->GetTextNodeForParaProps()
 == pTextNd) &&
-                    (!IsFromChapter() || IsHeadingContained(pOwnChapterNode, 
*pTextNd)))
+                if (useTextNodeForIndex(pTextNd, nMaxLevel, IsFromChapter(), 
pOwnChapterNode, pLayout))
                 {
                     InsertSorted(MakeSwTOXSortTabBase<SwTOXPara>(pLayout, 
*pTextNd, SwTOXElement::Template, i + 1));
                 }
@@ -1438,9 +1466,7 @@ void SwTOXBaseSection::UpdateSequence(const SwTextNode* 
pOwnChapterNode,
         SwTextNode& rTextNode = pTextField->GetTextNode();
         ::SetProgressState( 0, pDoc->GetDocShell() );
 
-        if (rTextNode.GetText().getLength() &&
-            rTextNode.getLayoutFrame(pLayout) &&
-            ( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, 
rTextNode))
+        if (useTextNodeForIndex(&rTextNode, -1, IsFromChapter(), 
pOwnChapterNode, pLayout)
             && (!pLayout || !pLayout->IsHideRedlines()
                 || 
!sw::IsFieldDeletedInModel(pDoc->getIDocumentRedlineAccess(), *pTextField)))
         {
@@ -1481,8 +1507,7 @@ void SwTOXBaseSection::UpdateAuthorities(const 
SwTOXInternational& rIntl,
         const SwTextNode& rTextNode = 
pFormatField->GetTextField()->GetTextNode();
         ::SetProgressState( 0, pDoc->GetDocShell() );
 
-        if (rTextNode.GetText().getLength() &&
-            rTextNode.getLayoutFrame(pLayout) &&
+        if (useTextNodeForIndex(&rTextNode, -1, false, nullptr, pLayout) &&
             (!pLayout || !pLayout->IsHideRedlines()
                 || 
!sw::IsFieldDeletedInModel(pDoc->getIDocumentRedlineAccess(), *pTextField)))
         {
@@ -1630,10 +1655,7 @@ void SwTOXBaseSection::UpdateContent( SwTOXElement 
eMyType,
                 }
             }
 
-            if (pCNd->getLayoutFrame(pLayout)
-                && (!pLayout || !pLayout->HasMergedParas()
-                    || pCNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden)
-                && ( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, 
*pCNd)))
+            if (useContentNodeForIndex(pCNd, IsFromChapter(), pOwnChapterNode, 
pLayout))
             {
                 std::unique_ptr<SwTOXPara> pNew( 
MakeSwTOXSortTabBase<SwTOXPara>(
                         pLayout, *pCNd, eMyType,
@@ -1670,10 +1692,7 @@ void SwTOXBaseSection::UpdateTable(const SwTextNode* 
pOwnChapterNode,
             while( nullptr != ( pCNd = SwNodes::GoNext( &aContentIdx ) ) &&
                 aContentIdx.GetIndex() < pTableNd->EndOfSectionIndex() )
             {
-                if (pCNd->getLayoutFrame(pLayout)
-                    && (!pLayout || !pLayout->HasMergedParas()
-                        || pCNd->GetRedlineMergeFlag() != 
SwNode::Merge::Hidden)
-                    && (!IsFromChapter() || 
IsHeadingContained(pOwnChapterNode, *pCNd)))
+                if (useContentNodeForIndex(pCNd, IsFromChapter(), 
pOwnChapterNode, pLayout))
                 {
                     std::unique_ptr<SwTOXTable> pNew(new SwTOXTable( *pCNd ));
                     if( IsLevelFromChapter() && TOX_TABLES != 
SwTOXBase::GetType())
diff --git a/sw/source/core/tox/tox.cxx b/sw/source/core/tox/tox.cxx
index ef38ff3a17b6..476ecd804166 100644
--- a/sw/source/core/tox/tox.cxx
+++ b/sw/source/core/tox/tox.cxx
@@ -197,6 +197,9 @@ void SwTOXMark::Notify(const SfxHint& rHint)
         // Check for being hidden by hidden redlines
         if (pLayout && pLayout->HasMergedParas() && 
sw::IsMarkHintHidden(*pLayout, rNode, rTextMark))
             return;
+        // Check for being hidden by hidden sections
+        if (auto pFrame(rNode.getLayoutFrame(pLayout)); !pFrame || 
pFrame->IsHiddenNow())
+            return;
         pCollectLayoutHint->m_rMarks.push_back(rTextMark);
     }
 }

Reply via email to