sw/inc/OnlineAccessibilityCheck.hxx                 |   24 +++++
 sw/source/core/txtnode/OnlineAccessibilityCheck.cxx |   89 +++++++++++++++-----
 2 files changed, 94 insertions(+), 19 deletions(-)

New commits:
commit c7db08cc6741d7d0edb0c9956b47dcab964caea4
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Mon Oct 24 22:19:06 2022 +0200
Commit:     Tomaž Vajngerl <[email protected]>
CommitDate: Tue Dec 13 09:12:08 2022 +0000

    sw: track content node with a11y issues, so the number is correct
    
    Track all content node with a11y issues and handle when they are
    deleted (with WeakContentNodeContainer). At update, recount the
    number of a11y issues that are contained in the content nodes and
    update the overall number.
    
    Change-Id: I254c62aba0d73a365f011b1609bcddec4dd71615
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141785
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    (cherry picked from commit ca03ea5c1ce7f1fa0702c004068a2592a723e669)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143704
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sw/inc/OnlineAccessibilityCheck.hxx 
b/sw/inc/OnlineAccessibilityCheck.hxx
index 48a639b9d656..9ec6f28ba6b1 100644
--- a/sw/inc/OnlineAccessibilityCheck.hxx
+++ b/sw/inc/OnlineAccessibilityCheck.hxx
@@ -15,15 +15,37 @@
 #include <svl/listener.hxx>
 #include <vcl/timer.hxx>
 #include <AccessibilityCheck.hxx>
+#include <map>
 
 struct SwPosition;
 class SwTextNode;
 
 namespace sw
 {
+/// Contains the content node and tracks if the node
+/// gets deleted.
+class WeakContentNodeContainer : public SvtListener
+{
+private:
+    SwContentNode* m_pNode;
+
+public:
+    WeakContentNodeContainer(SwContentNode* pNode);
+    ~WeakContentNodeContainer();
+
+    /// Is the node still alive or it was deleted?
+    bool isAlive();
+
+    /// Returns the pointer of the content node or nullptr if the node
+    /// got deleted.
+    SwContentNode* getNode();
+};
+
 class OnlineAccessibilityCheck : public SvtListener
 {
 private:
+    std::map<SwContentNode*, std::unique_ptr<WeakContentNodeContainer>> 
m_aNodes;
+
     SwDoc& m_rDocument;
     sw::AccessibilityCheck m_aAccessibilityCheck;
     SwContentNode* m_pPreviousNode;
@@ -31,6 +53,8 @@ private:
     sal_Int32 m_nAccessibilityIssues;
 
     void runCheck(SwContentNode* pNode);
+    void updateStatusbar();
+    void updateNodeStatus(SwContentNode* pContentNode);
 
 public:
     OnlineAccessibilityCheck(SwDoc& rDocument);
diff --git a/sw/source/core/txtnode/OnlineAccessibilityCheck.cxx 
b/sw/source/core/txtnode/OnlineAccessibilityCheck.cxx
index e34738466d99..a2a9783c3fd1 100644
--- a/sw/source/core/txtnode/OnlineAccessibilityCheck.cxx
+++ b/sw/source/core/txtnode/OnlineAccessibilityCheck.cxx
@@ -29,6 +29,32 @@
 
 namespace sw
 {
+WeakContentNodeContainer::WeakContentNodeContainer(SwContentNode* pNode)
+    : m_pNode(pNode)
+{
+    if (m_pNode)
+    {
+        EndListeningAll();
+        StartListening(m_pNode->GetNotifier());
+    }
+}
+
+WeakContentNodeContainer::~WeakContentNodeContainer() { EndListeningAll(); }
+
+bool WeakContentNodeContainer::isAlive()
+{
+    if (!HasBroadcaster())
+        m_pNode = nullptr;
+    return m_pNode;
+}
+
+SwContentNode* WeakContentNodeContainer::getNode()
+{
+    if (isAlive())
+        return m_pNode;
+    return nullptr;
+}
+
 OnlineAccessibilityCheck::OnlineAccessibilityCheck(SwDoc& rDocument)
     : m_rDocument(rDocument)
     , m_aAccessibilityCheck(&m_rDocument)
@@ -38,6 +64,48 @@ OnlineAccessibilityCheck::OnlineAccessibilityCheck(SwDoc& 
rDocument)
 {
 }
 
+void OnlineAccessibilityCheck::updateNodeStatus(SwContentNode* pContentNode)
+{
+    m_nAccessibilityIssues = 0;
+
+    auto it = m_aNodes.find(pContentNode);
+    if (it == m_aNodes.end())
+    {
+        m_aNodes.emplace(pContentNode, 
std::make_unique<WeakContentNodeContainer>(pContentNode));
+    }
+
+    for (auto iterator = m_aNodes.begin(); iterator != m_aNodes.end();)
+    {
+        auto& pWeakContentNode = iterator->second;
+        if (pWeakContentNode->isAlive())
+        {
+            auto& rStatus = 
pWeakContentNode->getNode()->getAccessibilityCheckStatus();
+            if (rStatus.pCollection)
+            {
+                m_nAccessibilityIssues += 
rStatus.pCollection->getIssues().size();
+                ++iterator;
+            }
+            else
+            {
+                iterator = m_aNodes.erase(iterator);
+            }
+        }
+        else
+        {
+            iterator = m_aNodes.erase(iterator);
+        }
+    }
+}
+
+void OnlineAccessibilityCheck::updateStatusbar()
+{
+    SfxBindings* pBindings = m_rDocument.GetDocShell() && 
m_rDocument.GetDocShell()->GetDispatcher()
+                                 ? 
m_rDocument.GetDocShell()->GetDispatcher()->GetBindings()
+                                 : nullptr;
+    if (pBindings)
+        pBindings->Invalidate(FN_STAT_ACCESSIBILITY_CHECK);
+}
+
 void OnlineAccessibilityCheck::runCheck(SwContentNode* pContentNode)
 {
     m_aAccessibilityCheck.getIssueCollection().clear();
@@ -56,25 +124,8 @@ void OnlineAccessibilityCheck::runCheck(SwContentNode* 
pContentNode)
     pContentNode->getAccessibilityCheckStatus().pCollection
         = std::make_unique<sfx::AccessibilityIssueCollection>(aCollection);
 
-    m_nAccessibilityIssues = 0;
-    auto const& pNodes = m_rDocument.GetNodes();
-    for (SwNodeOffset n(0); n < pNodes.Count(); ++n)
-    {
-        SwNode* pCurrent = pNodes[n];
-        if (pCurrent && pCurrent->IsTextNode())
-        {
-            auto* pCurrentTextNode = pCurrent->GetTextNode();
-            auto& rStatus = pCurrentTextNode->getAccessibilityCheckStatus();
-            if (rStatus.pCollection)
-                m_nAccessibilityIssues += 
rStatus.pCollection->getIssues().size();
-        }
-    }
-
-    SfxBindings* pBindings = m_rDocument.GetDocShell() && 
m_rDocument.GetDocShell()->GetDispatcher()
-                                 ? 
m_rDocument.GetDocShell()->GetDispatcher()->GetBindings()
-                                 : nullptr;
-    if (pBindings)
-        pBindings->Invalidate(FN_STAT_ACCESSIBILITY_CHECK);
+    updateNodeStatus(pContentNode);
+    updateStatusbar();
 }
 
 void OnlineAccessibilityCheck::update(const SwPosition& rNewPos)

Reply via email to