sw/source/uibase/utlui/content.cxx |  182 +++++++++++++++++++++++++++++++------
 1 file changed, 155 insertions(+), 27 deletions(-)

New commits:
commit 026affeab6adfbe118e12470193da2d8d7985983
Author:     Jim Raykowski <[email protected]>
AuthorDate: Sun Dec 7 23:52:52 2025 -0900
Commit:     Jim Raykowski <[email protected]>
CommitDate: Fri Dec 19 06:17:07 2025 +0100

    SwNavigator: Improve determining visibility of content entries
    
    Ideally content entries in the Navigator tree are shown as 'grayed out'
    when the content they refer to in the the document view is not visible
    due to being in a hidden section or in outline content that is folded.
    Currently this doesn't happen for content in hidden sections. This patch
    makes content entries in the Navigator tree 'grayed out' when the
    content they refer to in the document view is in a hidden section.
    
    Change-Id: I1a0f39ee4a1c336a12f814a813b764a12a030c42
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195214
    Reviewed-by: Jim Raykowski <[email protected]>
    Tested-by: Jenkins

diff --git a/sw/source/uibase/utlui/content.cxx 
b/sw/source/uibase/utlui/content.cxx
index e9cb74db9314..f8ffcf017266 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -130,6 +130,8 @@
 
 #include <rootfrm.hxx>
 
+#include <doctxm.hxx>
+
 #define CTYPE_CNT   0
 #define CTYPE_CTT   1
 
@@ -270,6 +272,13 @@ namespace
         rWrtShell.LeaveAddMode();
         rWrtShell.EndAction();
     }
+
+    void lcl_MaybeSetInvisible(const SwWrtShell* pWrtShell, SwContent* pCnt, 
const SwContentNode* pNd)
+    {
+        if (!pNd || /*in folded content*/ 
!pNd->getLayoutFrame(pWrtShell->GetLayout())
+            || /*in hidden section*/ 
pNd->getLayoutFrame(pWrtShell->GetLayout())->IsHiddenNow())
+            pCnt->SetInvisible();
+    }
 }
 
 // Content, contains names and reference at the content type.
@@ -573,8 +582,9 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
 
                 auto pCnt(std::make_unique<SwOutlineContent>(this, aEntry, i, 
nLevel,
                                                         
m_pWrtShell->IsOutlineMovable(i), nYPos));
-                if (!pNode->getLayoutFrame(m_pWrtShell->GetLayout()))
-                    pCnt->SetInvisible();
+
+                lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
                 m_pMember->insert(std::move(pCnt));
             }
 
@@ -613,14 +623,27 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                     continue;
                 }
                 tools::Long nYPos = 0;
+                SwTable* pTable = SwTable::FindTable(&rTableFormat);
                 if (!m_bAlphabeticSort)
                 {
-                    if (SwTable* pTable = SwTable::FindTable(&rTableFormat))
+                    if (pTable)
                         nYPos = getYPos(*pTable->GetTableNode());
                 }
                 auto pCnt = std::make_unique<SwContent>(this, 
rTableFormat.GetName().toString(), nYPos);
-                if(!rTableFormat.IsVisible())
-                    pCnt->SetInvisible();
+
+                // visibility
+                const SwStartNode* pSectionNd = 
pTable->GetTableNode()->GetStartNode();
+                const SwContentNode* pNode = nullptr;
+                if (pSectionNd)
+                {
+                    if (SwNodeType::Start & pSectionNd->GetNodeType())
+                    {
+                        SwNodeIndex aIdx(*pSectionNd);
+                        pNode = SwNodes::GoNext(&aIdx);
+                    }
+                }
+                lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
                 m_pMember->insert(std::move(pCnt));
             }
 
@@ -652,7 +675,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
             nCount = formats.size();
             for (size_t i = 0; i < nCount; ++i)
             {
-                SwFrameFormat const*const pFrameFormat = formats[i];
+                const SwFrameFormat* pFrameFormat = formats[i];
                 const UIName sFrameName = pFrameFormat->GetName();
 
                 SwContent* pCnt;
@@ -670,8 +693,28 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                 {
                     pCnt = new SwContent(this, sFrameName.toString(), nYPos);
                 }
-                if(!pFrameFormat->IsVisible())
-                    pCnt->SetInvisible();
+
+                // visibility
+                const SwNode* pNode = 
pFrameFormat->GetAnchor().GetAnchorNode();
+                while (pNode /*&& pNode->IsStartNode()
+                       && pNode->GetStartNode()->GetStartNodeType()
+                              == SwStartNodeType::SwFlyStartNode*/
+                       && pFrameFormat
+                       && pFrameFormat->GetAnchor().GetAnchorId() == 
RndStdIds::FLY_AT_FLY
+                       && (pFrameFormat = pNode->GetFlyFormat()))
+                {
+                    pNode = pFrameFormat->GetAnchor().GetAnchorNode();
+                }
+                assert(pFrameFormat);
+                if (pFrameFormat
+                    && pFrameFormat->GetAnchor().GetAnchorId() != 
RndStdIds::FLY_AT_PAGE)
+                {
+                    if (pNode && pNode->IsContentNode())
+                        lcl_MaybeSetInvisible(m_pWrtShell, pCnt, 
pNode->GetContentNode());
+                    else
+                        pCnt->SetInvisible();
+                }
+
                 m_pMember->insert(std::unique_ptr<SwContent>(pCnt));
             }
 
@@ -702,6 +745,12 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                     //nYPos from 0 -> text::Bookmarks will be sorted 
alphabetically
                     auto pCnt(std::make_unique<SwContent>(this, 
rBkmName.toString(),
                                                           m_bAlphabeticSort ? 
0 : nYPos++));
+
+                    // visibility
+                    SwPosition& rPosition = (*ppBookmark)->GetMarkPos();
+                    const SwContentNode* pNode = rPosition.GetContentNode();
+                    lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
                     m_pMember->insert(std::move(pCnt));
                 }
             }
@@ -829,8 +878,11 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                 auto pCnt(std::make_unique<SwTextFieldContent>(this, sText,
                                                                
&pTextField->GetFormatField(),
                                                                
m_bAlphabeticSort ? 0 : nYPos++));
-                if 
(!pTextField->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout()))
-                    pCnt->SetInvisible();
+
+                // visibility
+                SwTextNode* pNode = &(pTextField->GetTextNode());
+                lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
                 m_pMember->insert(std::move(pCnt));
             }
         }
@@ -858,8 +910,11 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                           + " " + lcl_GetFootnoteText(*pTextFootnote);
                     auto pCnt(std::make_unique<SwTextFootnoteContent>(
                         this, sText, pTextFootnote, ++nPos));
-                    if 
(!pTextFootnote->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout()))
-                        pCnt->SetInvisible();
+
+                    // visibility
+                    const SwTextNode* pNode = &(pTextFootnote->GetTextNode());
+                    lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
                     m_pMember->insert(std::move(pCnt));
                 }
             }
@@ -894,8 +949,19 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                                             m_bAlphabeticSort ? 0 : 
getYPos(pNodeIndex->GetNode()),
                                                                 pFormat));
 
-                    if (!pFormat->IsVisible() || pSection->IsHidden())
-                        pCnt->SetInvisible();
+                    // visibility
+                    const SwSectionNode* pSectionNd = 
pFormat->GetSectionNode();
+                    const SwContentNode* pNode = nullptr;
+                    if (pSectionNd)
+                    {
+                        if (SwNodeType::Start & pSectionNd->GetNodeType())
+                        {
+                            SwNodeIndex aIdx(*pSectionNd);
+                            pNode = SwNodes::GoNext(&aIdx);
+                        }
+                    }
+                    lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
                     m_pMember->insert(std::move(pCnt));
                 }
 
@@ -915,21 +981,59 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
         break;
         case ContentTypeId::REFERENCE:
         {
-            std::vector<OUString> aRefMarks;
-            m_pWrtShell->GetRefMarks( &aRefMarks );
+            std::vector<OUString> aRefMarkNames;
+            m_pWrtShell->GetRefMarks( &aRefMarkNames );
 
             tools::Long nYPos = 0;
-            for (const auto& rRefMark : aRefMarks)
+            for (const auto& rRefMarkName : aRefMarkNames)
             {
-                m_pMember->insert(std::make_unique<SwContent>(this, rRefMark,
-                                                              
m_bAlphabeticSort ? 0 : nYPos++));
+                auto pCnt(std::make_unique<SwContent>(this, rRefMarkName,
+                                                      m_bAlphabeticSort ? 0 : 
nYPos++));
+
+                // visibility
+                const SwFormatRefMark* pFormatRefMark = 
m_pWrtShell->GetRefMark(SwMarkName(rRefMarkName));
+                const SwTextRefMark* pTextRefMark = 
pFormatRefMark->GetTextRefMark();
+                const SwTextNode* pNode = &(pTextRefMark->GetTextNode());
+                lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
+                m_pMember->insert(std::move(pCnt));
             }
         }
         break;
         case ContentTypeId::URLFIELD:
         {
+            // INetAttrs
             SwGetINetAttrs aArr;
-            m_pWrtShell->GetINetAttrs(aArr, false);
+
+            // Fill aArr using a modified verision of SwEditShell::GetINetAttrs
+            const SwCharFormats* pFormats = 
m_pWrtShell->GetDoc()->GetCharFormats();
+            for (auto n = pFormats->size(); 1 < n;)
+            {
+                SwIterator<SwTextINetFormat, SwCharFormat> 
aIter(*(*pFormats)[--n]);
+                for (SwTextINetFormat* pFnd = aIter.First(); pFnd; pFnd = 
aIter.Next())
+                {
+                    const SwTextNode* pTextNd = pFnd->GetpTextNode();
+                    if (pTextNd && pTextNd->GetNodes().IsDocNodes())
+                    {
+                        // tdf#52113, tdf#148312 Don't include table of 
contents hyperlinks
+                        if (const SwSectionNode* pSectNd = 
pTextNd->FindSectionNode();
+                            pSectNd && pSectNd->GetSection().GetType() == 
SectionType::ToxContent)
+                            continue;
+
+                        SwTextINetFormat& rAttr = *pFnd;
+                        OUString 
sText(pTextNd->GetExpandText(m_pWrtShell->GetLayout(),
+                                                              rAttr.GetStart(),
+                                                              *rAttr.GetEnd() 
- rAttr.GetStart()));
+                        sText = sText.replaceAll("\x0a", "");
+                        sText = comphelper::string::strip(sText, ' ');
+
+                        if (!sText.isEmpty())
+                        {
+                            aArr.emplace_back(sText, rAttr);
+                        }
+                    }
+                }
+            }
 
             if (m_bAlphabeticSort)
             {
@@ -939,6 +1043,11 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                                                     
r.rINetAttr.GetINetFormat().GetValue(),
                                                     
INetURLObject::DecodeMechanism::Unambiguous),
                                                              &r.rINetAttr, 0));
+
+                    // visiblity
+                    const SwTextNode* pNode = &(r.rINetAttr.GetTextNode());
+                    lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
                     m_pMember->insert(std::move(pCnt));
                 }
                 break;
@@ -1001,6 +1110,11 @@ void SwContentType::FillMemberList(bool* 
pbContentChanged)
                             
INetURLObject::decode(p->rINetAttr.GetINetFormat().GetValue(),
                                                   
INetURLObject::DecodeMechanism::Unambiguous),
                             &p->rINetAttr, ++n);
+
+                // visiblity
+                const SwTextNode* pNode = &(p->rINetAttr.GetTextNode());
+                lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), pNode);
+
                 m_pMember->insert(std::move(pCnt));
             }
         }
@@ -1014,11 +1128,22 @@ void SwContentType::FillMemberList(bool* 
pbContentChanged)
                 const SwTOXBase* pBase = m_pWrtShell->GetTOX( nTox );
                 UIName sTOXNm( pBase->GetTOXName() );
 
-                SwContent* pCnt = new SwTOXBaseContent(
-                        this, sTOXNm.toString(), m_bAlphabeticSort ? 0 : nTox, 
*pBase);
+                SwContent* pCnt = new SwTOXBaseContent(this, sTOXNm.toString(),
+                                                       m_bAlphabeticSort ? 0 : 
nTox, *pBase);
 
-                if(pBase && !pBase->IsVisible())
-                    pCnt->SetInvisible();
+                // visiblity
+                const SwContentNode* pNode = nullptr;
+                const SwSectionNode* pSectionNd
+                    = static_cast<const 
SwTOXBaseSection*>(pBase)->GetFormat()->GetSectionNode();
+                if (pSectionNd)
+                {
+                    if (SwNodeType::Start & pSectionNd->GetNodeType())
+                    {
+                        SwNodeIndex aIdx(*pSectionNd);
+                        pNode = SwNodes::GoNext(&aIdx);
+                    }
+                }
+                lcl_MaybeSetInvisible(m_pWrtShell, pCnt, pNode);
 
                 m_pMember->insert( std::unique_ptr<SwContent>(pCnt) );
                 const size_t nPos = m_pMember->size() - 1;
@@ -1046,14 +1171,17 @@ void SwContentType::FillMemberList(bool* 
pbContentChanged)
                         {
                             OUString sEntry = 
pFormatField->GetField()->GetPar2();
                             sEntry = RemoveNewline(sEntry);
+
                             std::unique_ptr<SwPostItContent> pCnt(new 
SwPostItContent(
                                                 this,
                                                 sEntry,
                                                 pFormatField,
                                                 nYPos));
-                            if 
(!pFormatField->GetTextField()->GetTextNode().getLayoutFrame(
-                                        m_pWrtShell->GetLayout()))
-                                pCnt->SetInvisible();
+
+                            // visibility
+                            SwTextNode* pNode = 
&pFormatField->GetTextField()->GetTextNode();
+                            lcl_MaybeSetInvisible(m_pWrtShell, pCnt.get(), 
pNode);
+
                             if (pOldMember)
                             {
                                 assert(pbContentChanged && "pbContentChanged 
is always set if pOldMember is");

Reply via email to