include/sfx2/AccessibilityIssue.hxx                        |    2 
 officecfg/registry/schema/org/openoffice/Office/Common.xcs |   10 +
 sfx2/source/accessibility/AccessibilityIssue.cxx           |    2 
 sw/Library_sw.mk                                           |    1 
 sw/inc/OnlineAccessibilityCheck.hxx                        |   43 ++++
 sw/inc/doc.hxx                                             |    6 
 sw/inc/ndtxt.hxx                                           |   12 +
 sw/source/core/crsr/crsrsh.cxx                             |    4 
 sw/source/core/doc/docnew.cxx                              |    4 
 sw/source/core/txtnode/OnlineAccessibilityCheck.cxx        |  124 +++++++++++++
 10 files changed, 207 insertions(+), 1 deletion(-)

New commits:
commit 0b96a1747fc3f96ca70fd159594fe1a478369da0
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Thu Oct 20 22:33:22 2022 +0200
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Tue Nov 15 00:03:41 2022 +0100

    sw: add online accessibility check implementation
    
    Change-Id: Ic68aa91b1cbf23ac305ad4e361c56b91556757ee
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141604
    Tested-by: Tomaž Vajngerl <qui...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/include/sfx2/AccessibilityIssue.hxx 
b/include/sfx2/AccessibilityIssue.hxx
index 0c22d9e19238..d1bf1ee11766 100644
--- a/include/sfx2/AccessibilityIssue.hxx
+++ b/include/sfx2/AccessibilityIssue.hxx
@@ -59,6 +59,8 @@ public:
     AccessibilityIssueCollection() = default;
 
     std::vector<std::shared_ptr<AccessibilityIssue>>& getIssues();
+
+    void clear();
 };
 
 } // end sfx namespace
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index 5c0ae14167c1..2505345a8a39 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -6338,6 +6338,16 @@
          </info>
          <value>false</value>
        </prop>
+       <prop oor:name="OnlineAccessibilityCheck" oor:type="xs:boolean" 
oor:nillable="false">
+        <info>
+          <desc>
+            Enables online accessibility check, which checks for accessibility 
issues inside the document structure
+            while the user edits the document.
+          </desc>
+          <label>Enable/Disable online accessibility check.</label>
+         </info>
+         <value>false</value>
+       </prop>
     </group>
     <group oor:name="ExternalApps" oor:extensible="true">
       <info>
diff --git a/sfx2/source/accessibility/AccessibilityIssue.cxx 
b/sfx2/source/accessibility/AccessibilityIssue.cxx
index b276faf54c3f..aa58c3924476 100644
--- a/sfx2/source/accessibility/AccessibilityIssue.cxx
+++ b/sfx2/source/accessibility/AccessibilityIssue.cxx
@@ -24,6 +24,8 @@ std::vector<std::shared_ptr<AccessibilityIssue>>& 
AccessibilityIssueCollection::
     return m_aIssues;
 }
 
+void AccessibilityIssueCollection::clear() { m_aIssues.clear(); }
+
 } // end sfx namespace
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index 483f00601b04..7785ba9b6254 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -430,6 +430,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
     sw/source/core/tox/ToxTextGenerator \
     sw/source/core/tox/ToxWhitespaceStripper \
     sw/source/core/txtnode/GrammarContact \
+    sw/source/core/txtnode/OnlineAccessibilityCheck \
     sw/source/core/txtnode/attrcontentcontrol \
     sw/source/core/txtnode/atrfld \
     sw/source/core/txtnode/atrflyin \
diff --git a/sw/inc/OnlineAccessibilityCheck.hxx 
b/sw/inc/OnlineAccessibilityCheck.hxx
new file mode 100644
index 000000000000..f27f867ce96b
--- /dev/null
+++ b/sw/inc/OnlineAccessibilityCheck.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include "ndindex.hxx"
+#include "ndtxt.hxx"
+#include <svl/listener.hxx>
+#include <vcl/timer.hxx>
+#include <AccessibilityCheck.hxx>
+
+struct SwPosition;
+class SwTextNode;
+
+namespace sw
+{
+class OnlineAccessibilityCheck : public SvtListener
+{
+private:
+    SwDoc& m_rDocument;
+    sw::AccessibilityCheck m_aAccessibilityCheck;
+    SwTextNode* m_pCurrentTextNode;
+    SwNodeOffset m_aCurrentNodeIndex;
+    sal_Int32 m_nAccessibilityIssues;
+
+    void runCheck(SwTextNode* pTextNode);
+
+public:
+    OnlineAccessibilityCheck(SwDoc& rDocument);
+    void update(const SwPosition& rNewPos);
+    sal_Int32 getNumberOfAccessibilityIssues() { return 
m_nAccessibilityIssues; }
+};
+
+} // end sw
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index de5ec6112a00..80aa234cc6e3 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -163,6 +163,7 @@ namespace sw {
     class DocumentStylePoolManager;
     class DocumentExternalDataManager;
     class GrammarContact;
+    class OnlineAccessibilityCheck;
 }
 
 namespace com::sun::star {
@@ -285,6 +286,7 @@ class SW_DLLPUBLIC SwDoc final
                                                                     document 
for a faster formatting */
 
     std::unique_ptr<sw::GrammarContact> mpGrammarContact; //< for grammar 
checking in paragraphs during editing
+    std::unique_ptr<sw::OnlineAccessibilityCheck> mpOnlineAccessibilityCheck;
 
     css::uno::Reference< css::script::vba::XVBAEventProcessor > mxVbaEvents;
     css::uno::Reference< ooo::vba::word::XFind > mxVbaFind;
@@ -1562,6 +1564,10 @@ public:
     bool ContainsHiddenChars() const;
 
     std::unique_ptr<sw::GrammarContact> const& getGrammarContact() const { 
return mpGrammarContact; }
+    std::unique_ptr<sw::OnlineAccessibilityCheck> const& 
getOnlineAccessibilityCheck() const
+    {
+        return mpOnlineAccessibilityCheck;
+    }
 
     /** Marks/Unmarks a list level of a certain list
 
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 42cc43380f1a..63b019cf8178 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -37,6 +37,7 @@
 #include <memory>
 #include <vector>
 #include <functional>
+#include <sfx2/AccessibilityIssue.hxx>
 
 class SfxHint;
 class SwNumRule;
@@ -101,6 +102,12 @@ struct ParagraphIdleData
     bool bAutoComplDirty = true;               ///< auto complete list dirty
 };
 
+struct AccessibilityCheckStatus
+{
+    std::unique_ptr<sfx::AccessibilityIssueCollection> pCollection;
+    bool bDirty = true;
+};
+
 } // end namespace sw
 
 /// SwTextNode is a paragraph in the document model.
@@ -128,6 +135,7 @@ class SW_DLLPUBLIC SwTextNode final
     OUString m_Text;
 
     mutable sw::ParagraphIdleData m_aParagraphIdleData;
+    mutable sw::AccessibilityCheckStatus m_aAccessibilityCheckStatus;
 
     /** Some of the chars this para are hidden. Paragraph has to be reformatted
        on changing the view to print preview. */
@@ -234,6 +242,10 @@ public:
 
     /// End: Data collected during idle time
 
+    sw::AccessibilityCheckStatus& getAccessibilityCheckStatus()
+    {
+        return m_aAccessibilityCheckStatus;
+    }
 
 public:
     using SwContentNode::GetAttr;
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 0267990c8741..97df404d39ec 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -56,6 +56,7 @@
 #include <vcl/svapp.hxx>
 #include <vcl/settings.hxx>
 #include <GrammarContact.hxx>
+#include <OnlineAccessibilityCheck.hxx>
 #include <comphelper/flagguard.hxx>
 #include <strings.hrc>
 #include <IDocumentLayoutAccess.hxx>
@@ -1504,7 +1505,10 @@ void SwCursorShell::UpdateCursorPos()
     }
     auto* pDoc = GetDoc();
     if (pDoc)
+    {
         
pDoc->getGrammarContact()->updateCursorPosition(*m_pCurrentCursor->GetPoint());
+        
pDoc->getOnlineAccessibilityCheck()->update(*m_pCurrentCursor->GetPoint());
+    }
 
     --mnStartAction;
     if( aOldSz != GetDocSize() )
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 07456301f42e..8dc280e2853e 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -76,6 +76,7 @@
 #include <istyleaccess.hxx>
 #include "swstylemanager.hxx"
 #include <GrammarContact.hxx>
+#include <OnlineAccessibilityCheck.hxx>
 #include <tblafmt.hxx>
 #include <MarkManager.hxx>
 #include <UndoManager.hxx>
@@ -250,6 +251,7 @@ SwDoc::SwDoc()
     mpNumRuleTable( new SwNumRuleTable ),
     mpExtInputRing( nullptr ),
     mpGrammarContact(new sw::GrammarContact),
+    mpOnlineAccessibilityCheck(new sw::OnlineAccessibilityCheck(*this)),
     mpCellStyles(new SwCellStyleTable),
     mReferenceCount(0),
     mbDtor(false),
@@ -271,7 +273,6 @@ SwDoc::SwDoc()
     mbIsPrepareSelAll(false),
     meDictionaryMissing( MissingDictionary::Undefined ),
     mbContainsAtPageObjWithContentAnchor(false), //#i119292#, fdo#37024
-
     meDocType(DOCTYPE_NATIVE)
 {
     // The DrawingLayer ItemPool which is used as 2nd pool for Writer 
documents' pool
@@ -408,6 +409,7 @@ SwDoc::~SwDoc()
     }
 
     mpGrammarContact.reset();
+    mpOnlineAccessibilityCheck.reset();
 
     getIDocumentTimerAccess().StopIdling();   // stop idle timer
 
diff --git a/sw/source/core/txtnode/OnlineAccessibilityCheck.cxx 
b/sw/source/core/txtnode/OnlineAccessibilityCheck.cxx
new file mode 100644
index 000000000000..109bac52545b
--- /dev/null
+++ b/sw/source/core/txtnode/OnlineAccessibilityCheck.cxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <OnlineAccessibilityCheck.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <txtfrm.hxx>
+#include <officecfg/Office/Common.hxx>
+
+namespace sw
+{
+OnlineAccessibilityCheck::OnlineAccessibilityCheck(SwDoc& rDocument)
+    : m_rDocument(rDocument)
+    , m_aAccessibilityCheck(&m_rDocument)
+    , m_pCurrentTextNode(nullptr)
+    , m_aCurrentNodeIndex(-1)
+    , m_nAccessibilityIssues(0)
+{
+}
+
+void OnlineAccessibilityCheck::runCheck(SwTextNode* pTextNode)
+{
+    m_aAccessibilityCheck.checkNode(pTextNode);
+
+    for (SwFrameFormat* const& pFrameFormat : pTextNode->GetAnchoredFlys())
+    {
+        SdrObject* pObject = pFrameFormat->FindSdrObject();
+        if (pObject)
+            m_aAccessibilityCheck.checkObject(pObject);
+    }
+
+    auto aCollection = m_aAccessibilityCheck.getIssueCollection();
+
+    pTextNode->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* pNode = pNodes[n];
+        if (pNode && pNode->IsTextNode())
+        {
+            auto* pCurrentTextNode = pNode->GetTextNode();
+            auto& rStatus = pCurrentTextNode->getAccessibilityCheckStatus();
+            if (rStatus.pCollection)
+                m_nAccessibilityIssues += 
rStatus.pCollection->getIssues().size();
+        }
+    }
+}
+
+void OnlineAccessibilityCheck::update(const SwPosition& rNewPos)
+{
+    bool bOnlineCheckStatus
+        = 
officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::get();
+
+    if (!bOnlineCheckStatus)
+        return;
+
+    if (!HasBroadcaster())
+    {
+        m_pCurrentTextNode = nullptr;
+        m_aCurrentNodeIndex = SwNodeOffset(-1);
+    }
+
+    auto aNodeIndex = rNewPos.GetNodeIndex();
+
+    m_aAccessibilityCheck.getIssueCollection().clear();
+
+    SwTextNode* pTextNode = rNewPos.GetNode().GetTextNode();
+    if (!pTextNode)
+    {
+        m_pCurrentTextNode = nullptr;
+        m_aCurrentNodeIndex = SwNodeOffset(-1);
+        return;
+    }
+
+    if (pTextNode == m_pCurrentTextNode)
+    {
+        if (m_aCurrentNodeIndex != aNodeIndex && m_aCurrentNodeIndex >= 
SwNodeOffset(0)
+            && m_aCurrentNodeIndex < pTextNode->GetNodes().Count())
+        {
+            pTextNode = 
pTextNode->GetNodes()[m_aCurrentNodeIndex]->GetTextNode();
+
+            if (pTextNode)
+            {
+                runCheck(pTextNode);
+            }
+        }
+    }
+    else if (m_pCurrentTextNode)
+    {
+        runCheck(m_pCurrentTextNode);
+    }
+
+    m_aCurrentNodeIndex = aNodeIndex;
+
+    if (pTextNode && m_pCurrentTextNode != pTextNode)
+    {
+        EndListeningAll();
+        StartListening(pTextNode->GetNotifier());
+        m_pCurrentTextNode = pTextNode;
+    }
+}
+
+} // end sw
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to