[Libreoffice-commits] core.git: Branch 'feature/accessibilitycheck' - 9 commits - include/svx svx/source sw/CppunitTest_sw_core_accessibilitycheck.mk sw/Module_sw.mk sw/qa sw/source

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Sun Dec 15 09:59:38 UTC 2019


 include/svx/AccessibilityCheck.hxx                       |   60 +
 include/svx/AccessibilityCheckDialog.hxx                 |    9 
 svx/source/dialog/AccessibilityCheckDialog.cxx           |    4 
 sw/CppunitTest_sw_core_accessibilitycheck.mk             |   68 ++
 sw/Module_sw.mk                                          |    1 
 sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx |   40 +
 sw/qa/core/accessibilitycheck/data/DocumentTest.odt      |binary
 sw/source/core/access/AccessibilityCheck.cxx             |  504 +++++++++++++--
 sw/source/core/inc/AccessibilityCheck.hxx                |   20 
 sw/source/uibase/shells/basesh.cxx                       |    4 
 10 files changed, 640 insertions(+), 70 deletions(-)

New commits:
commit b6c90fc5e9ccfb91807ec28d785082d39a8a8421
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 15 10:51:39 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 15 10:51:39 2019 +0100

    acc. check: text vs. background contrast check
    
    Contrast between text and background shouldn't be too low (under
    4.5). The way how to calculate the contrast is defined by the
    WCAG21.
    
    Change-Id: Ic52ab68ba0ec6a4ab58e6b01afe74e8e7eeae104

diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index ee3a0b52b0a0..062bea8f18fb 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -23,6 +23,8 @@
 #include <tools/urlobj.hxx>
 #include <editeng/langitem.hxx>
 #include <charatr.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
 
 namespace sw
 {
@@ -36,6 +38,7 @@ OUString sHyperlinkTextIsLink("Hyperlink text is the same as the link address '%
 OUString sDocumentDefaultLanguage("Document default language is not set");
 OUString sStyleNoLanguage("Style '%STYLE_NAME%' has no language set");
 OUString sDocumentTitle("Document title is not set");
+OUString sTextContrast("Text contrast is too low.");
 }
 
 class BaseCheck
@@ -262,6 +265,140 @@ public:
     }
 };
 
+namespace
+{
+// Based on https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
+double calculateRelativeLuminance(Color const& rColor)
+{
+    // Convert to BColor which has R, G, B colors components
+    // represented by a floating point number from [0.0, 1.0]
+    const basegfx::BColor aBColor = rColor.getBColor();
+
+    double r = aBColor.getRed();
+    double g = aBColor.getGreen();
+    double b = aBColor.getBlue();
+
+    // Calculate the values according to the described algorithm
+    r = (r <= 0.03928) ? r / 12.92 : std::pow((r + 0.055) / 1.055, 2.4);
+    g = (g <= 0.03928) ? g / 12.92 : std::pow((g + 0.055) / 1.055, 2.4);
+    b = (b <= 0.03928) ? b / 12.92 : std::pow((b + 0.055) / 1.055, 2.4);
+
+    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
+}
+
+// TODO move to common color tools (BColorTools maybe)
+// Based on https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
+double calculateContrastRatio(Color const& rColor1, Color const& rColor2)
+{
+    const double fLuminance1 = calculateRelativeLuminance(rColor1);
+    const double fLuminance2 = calculateRelativeLuminance(rColor2);
+    const std::pair<const double, const double> aMinMax = std::minmax(fLuminance1, fLuminance2);
+
+    // (L1 + 0.05) / (L2 + 0.05)
+    // L1 is the lighter color (greater luminance value)
+    // L2 is the darker color (smaller luminance value)
+    return (aMinMax.second + 0.05) / (aMinMax.first + 0.05);
+}
+}
+
+class TextContrastCheck : public NodeCheck
+{
+private:
+    void checkTextRange(uno::Reference<text::XTextRange> const& xTextRange,
+                        uno::Reference<text::XTextContent> const& xParagraph, SwTextNode* pTextNode)
+    {
+        sal_Int32 nParaBackColor;
+        uno::Reference<beans::XPropertySet> xParagraphProperties(xParagraph, uno::UNO_QUERY);
+        xParagraphProperties->getPropertyValue("ParaBackColor") >>= nParaBackColor;
+
+        uno::Reference<beans::XPropertySet> xProperties(xTextRange, uno::UNO_QUERY);
+        if (xProperties.is())
+        {
+            // Forground color
+            sal_Int32 nCharColor;
+            xProperties->getPropertyValue("CharColor") >>= nCharColor;
+            Color aForegroundColor(nCharColor);
+            if (aForegroundColor == COL_AUTO)
+                return;
+
+            const SwPageDesc* pPageDescription = pTextNode->FindPageDesc();
+            const SwFrameFormat& rPageFormat = pPageDescription->GetMaster();
+            const SwAttrSet& rPageSet = rPageFormat.GetAttrSet();
+
+            const XFillStyleItem* pXFillStyleItem(
+                rPageSet.GetItem<XFillStyleItem>(XATTR_FILLSTYLE, false));
+            Color aPageBackground;
+
+            if (pXFillStyleItem->GetValue() == css::drawing::FillStyle_SOLID)
+            {
+                const XFillColorItem* rXFillColorItem
+                    = rPageSet.GetItem<XFillColorItem>(XATTR_FILLCOLOR, false);
+                aPageBackground = rXFillColorItem->GetColorValue();
+            }
+
+            sal_Int32 nCharBackColor;
+            sal_Int16 eRelief;
+
+            xProperties->getPropertyValue("CharBackColor") >>= nCharBackColor;
+            xProperties->getPropertyValue("CharRelief") >>= eRelief;
+
+            // Determine the background color
+            // Try Character background (highlight)
+            Color aBackgroundColor(nCharBackColor);
+
+            // If not character background color, try paragraph background color
+            if (aBackgroundColor == COL_AUTO)
+                aBackgroundColor = Color(nParaBackColor);
+
+            // If not paragraph background color, try page color
+            if (aBackgroundColor == COL_AUTO)
+                aBackgroundColor = aPageBackground;
+
+            // If not page color, assume white background color
+            if (aBackgroundColor == COL_AUTO)
+                aBackgroundColor = COL_WHITE;
+
+            double fContrastRatio = calculateContrastRatio(aForegroundColor, aBackgroundColor);
+            if (fContrastRatio < 4.5)
+            {
+                svx::AccessibilityCheckResult aResult;
+                aResult.m_aIssueText = sTextContrast;
+                m_rResultCollection.push_back(aResult);
+            }
+        }
+    }
+
+public:
+    TextContrastCheck(
+        std::vector<svx::AccessibilityCheckResult>& rAccessibilityCheckResultCollection)
+        : NodeCheck(rAccessibilityCheckResultCollection)
+    {
+    }
+
+    void check(SwNode* pCurrent) override
+    {
+        if (pCurrent->IsTextNode())
+        {
+            SwTextNode* pTextNode = pCurrent->GetTextNode();
+            uno::Reference<text::XTextContent> xParagraph;
+            xParagraph = SwXParagraph::CreateXParagraph(*pTextNode->GetDoc(), pTextNode);
+            if (xParagraph.is())
+            {
+                uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph,
+                                                                             uno::UNO_QUERY);
+                uno::Reference<container::XEnumeration> xRunEnum
+                    = xRunEnumAccess->createEnumeration();
+                while (xRunEnum->hasMoreElements())
+                {
+                    uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
+                    if (xRun.is())
+                        checkTextRange(xRun, xParagraph, pTextNode);
+                }
+            }
+        }
+    }
+};
+
 class DocumentCheck : public BaseCheck
 {
 public:
@@ -378,6 +515,7 @@ void AccessibilityCheck::check()
     aNodeChecks.push_back(std::make_unique<TableNodeMergeSplitCheck>(m_aResultCollection));
     aNodeChecks.push_back(std::make_unique<NumberingCheck>(m_aResultCollection));
     aNodeChecks.push_back(std::make_unique<HyperlinkCheck>(m_aResultCollection));
+    aNodeChecks.push_back(std::make_unique<TextContrastCheck>(m_aResultCollection));
 
     auto const& pNodes = m_pDoc->GetNodes();
     SwNode* pNode = nullptr;
commit 6ced3dc356a5bb27388df66476da62703e32498b
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 15 10:41:05 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 15 10:41:05 2019 +0100

    acc. check: introduce AccessibilityCheckTest + document test
    
    This adds AccessibilityCheckTest to test that AccessibilityCheck
    returns correct issues for documents. This in addition adds 2
    tests for document title and document/style language.
    
    Change-Id: I71f3b0de0af7a08507f2b90b46847010948bc8cb

diff --git a/include/svx/AccessibilityCheck.hxx b/include/svx/AccessibilityCheck.hxx
index 66b18ab6386c..526082b42a4d 100644
--- a/include/svx/AccessibilityCheck.hxx
+++ b/include/svx/AccessibilityCheck.hxx
@@ -17,10 +17,24 @@
 
 namespace svx
 {
+enum class AccessibilityIssueID
+{
+    UNSPECIFIED, // TODO: remove - temporary
+    DOCUMENT_TITLE,
+    DOCUMENT_LANGUAGE,
+    STYLE_LANGUAGE
+};
+
 class SVX_DLLPUBLIC AccessibilityCheckResult final
 {
 public:
+    AccessibilityIssueID m_eIssueID;
     OUString m_aIssueText;
+
+    AccessibilityCheckResult(AccessibilityIssueID eIssueID = AccessibilityIssueID::UNSPECIFIED)
+        : m_eIssueID(eIssueID)
+    {
+    }
 };
 
 class SVX_DLLPUBLIC AccessibilityCheck
diff --git a/sw/CppunitTest_sw_core_accessibilitycheck.mk b/sw/CppunitTest_sw_core_accessibilitycheck.mk
new file mode 100644
index 000000000000..e8ca263bd26b
--- /dev/null
+++ b/sw/CppunitTest_sw_core_accessibilitycheck.mk
@@ -0,0 +1,68 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# 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/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sw_core_accessibilitycheck))
+
+$(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_accessibilitycheck))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_core_accessibilitycheck, \
+    sw/qa/core/accessibilitycheck/AccessibilityCheckTest \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_core_accessibilitycheck, \
+    comphelper \
+    cppu \
+    cppuhelper \
+    sal \
+    sfx \
+    sw \
+    test \
+    unotest \
+    utl \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_core_accessibilitycheck,\
+    boost_headers \
+    libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sw_core_accessibilitycheck,\
+    -I$(SRCDIR)/sw/inc \
+    -I$(SRCDIR)/sw/source/core/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
+    -I$(SRCDIR)/sw/qa/inc \
+    $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,sw_core_accessibilitycheck,\
+    udkapi \
+    offapi \
+    oovbaapi \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_core_accessibilitycheck))
+$(eval $(call gb_CppunitTest_use_vcl,sw_core_accessibilitycheck))
+
+$(eval $(call gb_CppunitTest_use_rdb,sw_core_accessibilitycheck,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sw_core_accessibilitycheck,\
+    officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_core_accessibilitycheck))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,sw_core_accessibilitycheck, \
+    modules/swriter \
+))
+
+$(eval $(call gb_CppunitTest_use_more_fonts,sw_core_accessibilitycheck))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index 2dbd5f161f22..ea7a222dbcac 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -105,6 +105,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
     CppunitTest_sw_apitests \
     CppunitTest_sw_unowriter \
     CppunitTest_sw_core_text \
+    CppunitTest_sw_core_accessibilitycheck \
 ))
 
 ifneq ($(DISABLE_GUI),TRUE)
diff --git a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
new file mode 100644
index 000000000000..eff09430e92d
--- /dev/null
+++ b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
@@ -0,0 +1,40 @@
+/* -*- 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/.
+ */
+
+#include <swmodeltestbase.hxx>
+#include <wrtsh.hxx>
+#include <AccessibilityCheck.hxx>
+
+class AccessibilityCheckTest : public SwModelTestBase
+{
+public:
+    SwDoc* createDoc(const char* pName = nullptr)
+    {
+        load("/sw/qa/core/accessibilitycheck/data/", pName);
+        SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+        CPPUNIT_ASSERT(pTextDoc);
+        return pTextDoc->GetDocShell()->GetDoc();
+    }
+};
+
+CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testCheck)
+{
+    SwDoc* pDoc = createDoc("DocumentTest.odt");
+    CPPUNIT_ASSERT(pDoc);
+    sw::AccessibilityCheck aCheck(pDoc);
+    aCheck.check();
+    auto& aResults = aCheck.getResultCollecton();
+    CPPUNIT_ASSERT_EQUAL(size_t(2), aResults.size());
+    CPPUNIT_ASSERT_EQUAL(svx::AccessibilityIssueID::DOCUMENT_LANGUAGE, aResults[0].m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(svx::AccessibilityIssueID::DOCUMENT_TITLE, aResults[1].m_eIssueID);
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/accessibilitycheck/data/DocumentTest.odt b/sw/qa/core/accessibilitycheck/data/DocumentTest.odt
new file mode 100644
index 000000000000..65b9a7c2fd46
Binary files /dev/null and b/sw/qa/core/accessibilitycheck/data/DocumentTest.odt differ
diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index 498b4d968d9d..ee3a0b52b0a0 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -290,7 +290,7 @@ public:
         LanguageType eLanguage = rLang.GetLanguage();
         if (eLanguage == LANGUAGE_NONE)
         {
-            svx::AccessibilityCheckResult aResult;
+            svx::AccessibilityCheckResult aResult(svx::AccessibilityIssueID::DOCUMENT_LANGUAGE);
             aResult.m_aIssueText = sDocumentDefaultLanguage;
             m_rResultCollection.push_back(aResult);
         }
@@ -301,7 +301,8 @@ public:
                 const SwAttrSet& rAttrSet = pTextFormatCollection->GetAttrSet();
                 if (rAttrSet.GetLanguage(false).GetLanguage() == LANGUAGE_NONE)
                 {
-                    svx::AccessibilityCheckResult aResult;
+                    svx::AccessibilityCheckResult aResult(
+                        svx::AccessibilityIssueID::STYLE_LANGUAGE);
                     OUString sName = pTextFormatCollection->GetName();
                     aResult.m_aIssueText = sStyleNoLanguage.replaceAll("%STYLE_NAME%", sName);
                     m_rResultCollection.push_back(aResult);
@@ -331,7 +332,7 @@ public:
             OUString sTitle = xDocumentProperties->getTitle();
             if (sTitle.isEmpty())
             {
-                svx::AccessibilityCheckResult aResult;
+                svx::AccessibilityCheckResult aResult(svx::AccessibilityIssueID::DOCUMENT_TITLE);
                 aResult.m_aIssueText = sDocumentTitle;
                 m_rResultCollection.push_back(aResult);
             }
diff --git a/sw/source/core/inc/AccessibilityCheck.hxx b/sw/source/core/inc/AccessibilityCheck.hxx
index 9e77ca15e125..30bcb90e00a1 100644
--- a/sw/source/core/inc/AccessibilityCheck.hxx
+++ b/sw/source/core/inc/AccessibilityCheck.hxx
@@ -16,7 +16,7 @@
 
 namespace sw
 {
-class AccessibilityCheck final : public svx::AccessibilityCheck
+class SW_DLLPUBLIC AccessibilityCheck final : public svx::AccessibilityCheck
 {
 private:
     SwDoc* m_pDoc;
commit a836d0e79acd82b9fe87b2a9ec36435832629d32
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 15 10:26:22 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 15 10:34:55 2019 +0100

    acc. check: check document contains a document title (metadata)
    
    Change-Id: I09dd2143153e787730d1528de030d8777edcb05f

diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index e342df2e5bd2..498b4d968d9d 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -12,11 +12,13 @@
 #include <ndgrf.hxx>
 #include <ndole.hxx>
 #include <ndtxt.hxx>
+#include <docsh.hxx>
 #include <IDocumentDrawModelAccess.hxx>
 #include <drawdoc.hxx>
 #include <svx/svdpage.hxx>
 #include <swtable.hxx>
 #include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 #include <unoparagraph.hxx>
 #include <tools/urlobj.hxx>
 #include <editeng/langitem.hxx>
@@ -33,6 +35,7 @@ OUString sFakeNumbering("Fake numbering '%NUMBERING%'");
 OUString sHyperlinkTextIsLink("Hyperlink text is the same as the link address '%LINK%'");
 OUString sDocumentDefaultLanguage("Document default language is not set");
 OUString sStyleNoLanguage("Style '%STYLE_NAME%' has no language set");
+OUString sDocumentTitle("Document title is not set");
 }
 
 class BaseCheck
@@ -308,6 +311,34 @@ public:
     }
 };
 
+class DocumentTitleCheck : public DocumentCheck
+{
+public:
+    DocumentTitleCheck(std::vector<svx::AccessibilityCheckResult>& rResultCollection)
+        : DocumentCheck(rResultCollection)
+    {
+    }
+
+    void check(SwDoc* pDoc) override
+    {
+        SwDocShell* pShell = pDoc->GetDocShell();
+        if (pShell)
+        {
+            const uno::Reference<document::XDocumentPropertiesSupplier> xDPS(pShell->GetModel(),
+                                                                             uno::UNO_QUERY_THROW);
+            const uno::Reference<document::XDocumentProperties> xDocumentProperties(
+                xDPS->getDocumentProperties());
+            OUString sTitle = xDocumentProperties->getTitle();
+            if (sTitle.isEmpty())
+            {
+                svx::AccessibilityCheckResult aResult;
+                aResult.m_aIssueText = sDocumentTitle;
+                m_rResultCollection.push_back(aResult);
+            }
+        }
+    }
+};
+
 // Check Shapes, TextBox
 void AccessibilityCheck::checkObject(SdrObject* pObject)
 {
@@ -334,6 +365,7 @@ void AccessibilityCheck::check()
 
     std::vector<std::unique_ptr<DocumentCheck>> aDocumentChecks;
     aDocumentChecks.push_back(std::make_unique<DocumentDefaultLanguageCheck>(m_aResultCollection));
+    aDocumentChecks.push_back(std::make_unique<DocumentTitleCheck>(m_aResultCollection));
 
     for (std::unique_ptr<DocumentCheck>& rpDocumentCheck : aDocumentChecks)
     {
commit 0125875a3a0ae61d052519f8dbfb70ae0c1f200e
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 15 10:19:24 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 15 10:33:43 2019 +0100

    acc. check: check document default language and style language
    
    This checks hat the defualt language of the document is set and
    in addition that the used styles also have the default language
    set. Accessibility requires the language always be set.
    
    Change-Id: I6ea36e6e8b30289cdb35311da9470f856a847b38

diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index 230a006a7294..e342df2e5bd2 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -19,6 +19,8 @@
 #include <com/sun/star/text/XTextContent.hpp>
 #include <unoparagraph.hxx>
 #include <tools/urlobj.hxx>
+#include <editeng/langitem.hxx>
+#include <charatr.hxx>
 
 namespace sw
 {
@@ -29,19 +31,31 @@ OUString sNoAlt("No alt text for graphic '%OBJECT_NAME%'");
 OUString sTableMergeSplit("Table '%OBJECT_NAME%' contains merges or splits");
 OUString sFakeNumbering("Fake numbering '%NUMBERING%'");
 OUString sHyperlinkTextIsLink("Hyperlink text is the same as the link address '%LINK%'");
+OUString sDocumentDefaultLanguage("Document default language is not set");
+OUString sStyleNoLanguage("Style '%STYLE_NAME%' has no language set");
 }
 
-class NodeCheck
+class BaseCheck
 {
 protected:
     std::vector<svx::AccessibilityCheckResult>& m_rResultCollection;
 
 public:
-    NodeCheck(std::vector<svx::AccessibilityCheckResult>& rResultCollection)
+    BaseCheck(std::vector<svx::AccessibilityCheckResult>& rResultCollection)
         : m_rResultCollection(rResultCollection)
     {
     }
-    virtual ~NodeCheck() {}
+    virtual ~BaseCheck() {}
+};
+
+class NodeCheck : public BaseCheck
+{
+public:
+    NodeCheck(std::vector<svx::AccessibilityCheckResult>& rResultCollection)
+        : BaseCheck(rResultCollection)
+    {
+    }
+
     virtual void check(SwNode* pCurrent) = 0;
 };
 
@@ -245,6 +259,55 @@ public:
     }
 };
 
+class DocumentCheck : public BaseCheck
+{
+public:
+    DocumentCheck(std::vector<svx::AccessibilityCheckResult>& rResultCollection)
+        : BaseCheck(rResultCollection)
+    {
+    }
+
+    virtual void check(SwDoc* pDoc) = 0;
+};
+
+// Check default language
+class DocumentDefaultLanguageCheck : public DocumentCheck
+{
+public:
+    DocumentDefaultLanguageCheck(std::vector<svx::AccessibilityCheckResult>& rResultCollection)
+        : DocumentCheck(rResultCollection)
+    {
+    }
+
+    void check(SwDoc* pDoc) override
+    {
+        // TODO maybe - also check RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE if CJK or CTL are enabled
+        const SvxLanguageItem& rLang
+            = static_cast<const SvxLanguageItem&>(pDoc->GetDefault(RES_CHRATR_LANGUAGE));
+        LanguageType eLanguage = rLang.GetLanguage();
+        if (eLanguage == LANGUAGE_NONE)
+        {
+            svx::AccessibilityCheckResult aResult;
+            aResult.m_aIssueText = sDocumentDefaultLanguage;
+            m_rResultCollection.push_back(aResult);
+        }
+        else
+        {
+            for (SwTextFormatColl* pTextFormatCollection : *pDoc->GetTextFormatColls())
+            {
+                const SwAttrSet& rAttrSet = pTextFormatCollection->GetAttrSet();
+                if (rAttrSet.GetLanguage(false).GetLanguage() == LANGUAGE_NONE)
+                {
+                    svx::AccessibilityCheckResult aResult;
+                    OUString sName = pTextFormatCollection->GetName();
+                    aResult.m_aIssueText = sStyleNoLanguage.replaceAll("%STYLE_NAME%", sName);
+                    m_rResultCollection.push_back(aResult);
+                }
+            }
+        }
+    }
+};
+
 // Check Shapes, TextBox
 void AccessibilityCheck::checkObject(SdrObject* pObject)
 {
@@ -269,6 +332,14 @@ void AccessibilityCheck::check()
     if (m_pDoc == nullptr)
         return;
 
+    std::vector<std::unique_ptr<DocumentCheck>> aDocumentChecks;
+    aDocumentChecks.push_back(std::make_unique<DocumentDefaultLanguageCheck>(m_aResultCollection));
+
+    for (std::unique_ptr<DocumentCheck>& rpDocumentCheck : aDocumentChecks)
+    {
+        rpDocumentCheck->check(m_pDoc);
+    }
+
     std::vector<std::unique_ptr<NodeCheck>> aNodeChecks;
     aNodeChecks.push_back(std::make_unique<NoTextNodeAltTextCheck>(m_aResultCollection));
     aNodeChecks.push_back(std::make_unique<TableNodeMergeSplitCheck>(m_aResultCollection));
commit 13a7fdcbdf000f9a52290459fc6294e086a9287b
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 15 10:12:01 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 15 10:12:01 2019 +0100

    acc. check: check hyperlink text doesn't contain the link
    
    The hyperlink text shouldn't be the URL too - for example the
    text shouldn't be "http://www.example.com"
    
    Change-Id: I69f7a742705aaa25da1a832ab05922d138b8ea0f

diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index 66d47b00095d..230a006a7294 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -16,6 +16,9 @@
 #include <drawdoc.hxx>
 #include <svx/svdpage.hxx>
 #include <swtable.hxx>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <unoparagraph.hxx>
+#include <tools/urlobj.hxx>
 
 namespace sw
 {
@@ -25,6 +28,7 @@ namespace
 OUString sNoAlt("No alt text for graphic '%OBJECT_NAME%'");
 OUString sTableMergeSplit("Table '%OBJECT_NAME%' contains merges or splits");
 OUString sFakeNumbering("Fake numbering '%NUMBERING%'");
+OUString sHyperlinkTextIsLink("Hyperlink text is the same as the link address '%LINK%'");
 }
 
 class NodeCheck
@@ -186,6 +190,61 @@ public:
     }
 };
 
+class HyperlinkCheck : public NodeCheck
+{
+private:
+    void checkTextRange(uno::Reference<text::XTextRange> const& xTextRange)
+    {
+        uno::Reference<beans::XPropertySet> xProperties(xTextRange, uno::UNO_QUERY);
+        if (xProperties->getPropertySetInfo()->hasPropertyByName("HyperLinkURL"))
+        {
+            OUString sHyperlink;
+            xProperties->getPropertyValue("HyperLinkURL") >>= sHyperlink;
+            if (!sHyperlink.isEmpty())
+            {
+                OUString sText = xTextRange->getString();
+                if (INetURLObject(sText) == INetURLObject(sHyperlink))
+                {
+                    svx::AccessibilityCheckResult aResult;
+                    aResult.m_aIssueText = sHyperlinkTextIsLink.replaceFirst("%LINK%", sHyperlink);
+                    m_rResultCollection.push_back(aResult);
+                }
+            }
+        }
+    }
+
+public:
+    HyperlinkCheck(std::vector<svx::AccessibilityCheckResult>& rAccessibilityCheckResultCollection)
+        : NodeCheck(rAccessibilityCheckResultCollection)
+    {
+    }
+
+    void check(SwNode* pCurrent) override
+    {
+        if (pCurrent->IsTextNode())
+        {
+            SwTextNode* pTextNode = pCurrent->GetTextNode();
+            uno::Reference<text::XTextContent> xParagraph
+                = SwXParagraph::CreateXParagraph(*pTextNode->GetDoc(), pTextNode);
+            if (xParagraph.is())
+            {
+                uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph,
+                                                                             uno::UNO_QUERY);
+                uno::Reference<container::XEnumeration> xRunEnum
+                    = xRunEnumAccess->createEnumeration();
+                while (xRunEnum->hasMoreElements())
+                {
+                    uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
+                    if (xRun.is())
+                    {
+                        checkTextRange(xRun);
+                    }
+                }
+            }
+        }
+    }
+};
+
 // Check Shapes, TextBox
 void AccessibilityCheck::checkObject(SdrObject* pObject)
 {
@@ -214,6 +273,7 @@ void AccessibilityCheck::check()
     aNodeChecks.push_back(std::make_unique<NoTextNodeAltTextCheck>(m_aResultCollection));
     aNodeChecks.push_back(std::make_unique<TableNodeMergeSplitCheck>(m_aResultCollection));
     aNodeChecks.push_back(std::make_unique<NumberingCheck>(m_aResultCollection));
+    aNodeChecks.push_back(std::make_unique<HyperlinkCheck>(m_aResultCollection));
 
     auto const& pNodes = m_pDoc->GetNodes();
     SwNode* pNode = nullptr;
commit 5c607584836bbe896a2baee50c77e87e6fef2917
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 15 09:57:29 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 15 09:57:29 2019 +0100

    acc. check: detect fake numbering
    
    Detect fake numbering, where numbering is not done using the
    Writer integrated numbering. This is done by checking the pattern
    how the paragraphs start. If paragraph starts with "2." (for
    example) and previous paragraph starts with "1.", then this is
    possible a fake numbering.
    
    Currently checking "1.", "(1)", "1)", "a.", "a)", "(a)".
    
    Change-Id: Ibdb725d944f50208c6c951531e291183244f38e8

diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index d38bba2c19d9..66d47b00095d 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -24,6 +24,7 @@ namespace
 // TODO move these to string file and look for a better name.
 OUString sNoAlt("No alt text for graphic '%OBJECT_NAME%'");
 OUString sTableMergeSplit("Table '%OBJECT_NAME%' contains merges or splits");
+OUString sFakeNumbering("Fake numbering '%NUMBERING%'");
 }
 
 class NodeCheck
@@ -145,6 +146,46 @@ public:
     }
 };
 
+class NumberingCheck : public NodeCheck
+{
+private:
+    SwTextNode* pPreviousTextNode;
+
+    const std::vector<std::pair<OUString, OUString>> constNumberingCombinations{
+        { "1.", "2." }, { "(1)", "(2)" }, { "1)", "2)" },   { "a.", "b." }, { "(a)", "(b)" },
+        { "a)", "b)" }, { "A.", "B." },   { "(A)", "(B)" }, { "A)", "B)" }
+    };
+
+public:
+    NumberingCheck(std::vector<svx::AccessibilityCheckResult>& rAccessibilityCheckResultCollection)
+        : NodeCheck(rAccessibilityCheckResultCollection)
+        , pPreviousTextNode(nullptr)
+    {
+    }
+
+    void check(SwNode* pCurrent) override
+    {
+        if (pCurrent->IsTextNode())
+        {
+            if (pPreviousTextNode)
+            {
+                for (auto& rPair : constNumberingCombinations)
+                {
+                    if (pCurrent->GetTextNode()->GetText().startsWith(rPair.second)
+                        && pPreviousTextNode->GetText().startsWith(rPair.first))
+                    {
+                        svx::AccessibilityCheckResult aResult;
+                        OUString sNumbering = rPair.first + " " + rPair.second + "...";
+                        aResult.m_aIssueText = sFakeNumbering.replaceAll("%NUMBERING%", sNumbering);
+                        m_rResultCollection.push_back(aResult);
+                    }
+                }
+            }
+            pPreviousTextNode = pCurrent->GetTextNode();
+        }
+    }
+};
+
 // Check Shapes, TextBox
 void AccessibilityCheck::checkObject(SdrObject* pObject)
 {
@@ -172,6 +213,7 @@ void AccessibilityCheck::check()
     std::vector<std::unique_ptr<NodeCheck>> aNodeChecks;
     aNodeChecks.push_back(std::make_unique<NoTextNodeAltTextCheck>(m_aResultCollection));
     aNodeChecks.push_back(std::make_unique<TableNodeMergeSplitCheck>(m_aResultCollection));
+    aNodeChecks.push_back(std::make_unique<NumberingCheck>(m_aResultCollection));
 
     auto const& pNodes = m_pDoc->GetNodes();
     SwNode* pNode = nullptr;
commit 167381b6c2c186c7339f53faefd53dfa20216bb4
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 8 21:14:41 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 8 21:14:41 2019 +0100

    acc. check: simplify var. name for acc. result check collection
    
    m_aAccessibilityCheckResultCollection to m_aResultCollection
    
    Change-Id: I979d60aaf5963c0fa0fb58fc2e0a89b77858110b

diff --git a/include/svx/AccessibilityCheck.hxx b/include/svx/AccessibilityCheck.hxx
index de240906697a..66b18ab6386c 100644
--- a/include/svx/AccessibilityCheck.hxx
+++ b/include/svx/AccessibilityCheck.hxx
@@ -26,7 +26,7 @@ public:
 class SVX_DLLPUBLIC AccessibilityCheck
 {
 protected:
-    std::vector<AccessibilityCheckResult> m_aAccessibilityCheckResultCollection;
+    std::vector<AccessibilityCheckResult> m_aResultCollection;
 
 public:
     virtual ~AccessibilityCheck() {}
@@ -35,7 +35,7 @@ public:
 
     std::vector<AccessibilityCheckResult> const& getResultCollecton()
     {
-        return m_aAccessibilityCheckResultCollection;
+        return m_aResultCollection;
     }
 };
 
diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index 24adf24dccad..d38bba2c19d9 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -29,11 +29,11 @@ OUString sTableMergeSplit("Table '%OBJECT_NAME%' contains merges or splits");
 class NodeCheck
 {
 protected:
-    std::vector<svx::AccessibilityCheckResult>& m_rAccessibilityCheckResultCollection;
+    std::vector<svx::AccessibilityCheckResult>& m_rResultCollection;
 
 public:
-    NodeCheck(std::vector<svx::AccessibilityCheckResult>& rAccessibilityCheckResultCollection)
-        : m_rAccessibilityCheckResultCollection(rAccessibilityCheckResultCollection)
+    NodeCheck(std::vector<svx::AccessibilityCheckResult>& rResultCollection)
+        : m_rResultCollection(rResultCollection)
     {
     }
     virtual ~NodeCheck() {}
@@ -54,14 +54,13 @@ class NoTextNodeAltTextCheck : public NodeCheck
             OUString sName = pNoTextNode->GetFlyFormat()->GetName();
             svx::AccessibilityCheckResult aResult;
             aResult.m_aIssueText = sNoAlt.replaceAll("%OBJECT_NAME%", sName);
-            m_rAccessibilityCheckResultCollection.push_back(aResult);
+            m_rResultCollection.push_back(aResult);
         }
     }
 
 public:
-    NoTextNodeAltTextCheck(
-        std::vector<svx::AccessibilityCheckResult>& rAccessibilityCheckResultCollection)
-        : NodeCheck(rAccessibilityCheckResultCollection)
+    NoTextNodeAltTextCheck(std::vector<svx::AccessibilityCheckResult>& rResultCollection)
+        : NodeCheck(rResultCollection)
     {
     }
 
@@ -91,7 +90,7 @@ private:
             OUString sName = rTable.GetTableStyleName();
             svx::AccessibilityCheckResult aResult;
             aResult.m_aIssueText = sTableMergeSplit.replaceAll("%OBJECT_NAME%", sName);
-            m_rAccessibilityCheckResultCollection.push_back(aResult);
+            m_rResultCollection.push_back(aResult);
         }
         else
         {
@@ -122,7 +121,7 @@ private:
                     OUString sName = rTable.GetTableStyleName();
                     svx::AccessibilityCheckResult aResult;
                     aResult.m_aIssueText = sTableMergeSplit.replaceAll("%OBJECT_NAME%", sName);
-                    m_rAccessibilityCheckResultCollection.push_back(aResult);
+                    m_rResultCollection.push_back(aResult);
                 }
             }
         }
@@ -160,7 +159,7 @@ void AccessibilityCheck::checkObject(SdrObject* pObject)
             OUString sName = pObject->GetName();
             svx::AccessibilityCheckResult aResult;
             aResult.m_aIssueText = sNoAlt.replaceAll("%OBJECT_NAME%", sName);
-            m_aAccessibilityCheckResultCollection.push_back(aResult);
+            m_aResultCollection.push_back(aResult);
         }
     }
 }
@@ -171,10 +170,8 @@ void AccessibilityCheck::check()
         return;
 
     std::vector<std::unique_ptr<NodeCheck>> aNodeChecks;
-    aNodeChecks.push_back(
-        std::make_unique<NoTextNodeAltTextCheck>(m_aAccessibilityCheckResultCollection));
-    aNodeChecks.push_back(
-        std::make_unique<TableNodeMergeSplitCheck>(m_aAccessibilityCheckResultCollection));
+    aNodeChecks.push_back(std::make_unique<NoTextNodeAltTextCheck>(m_aResultCollection));
+    aNodeChecks.push_back(std::make_unique<TableNodeMergeSplitCheck>(m_aResultCollection));
 
     auto const& pNodes = m_pDoc->GetNodes();
     SwNode* pNode = nullptr;
commit fea22b3d2e5cad6b5ad303c8420f84d77053a010
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 8 20:59:43 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 8 21:04:59 2019 +0100

    acc. check: Introduce NodeCheck for accessibility checks on nodes
    
    NodeCheck responsibility is to check a node for accessibility
    issues. For each node there are multiple node checks executed and
    currently there are 2 node check implementations:
    - NoTextNodeAltTextCheck
    - TableNodeMergeSplitCheck
    These 2 checks are converted from the current checks in the code.
    
    Change-Id: Idde7092536f094d936aa3d353f4512949ca36a60

diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index 42c10af26dcd..24adf24dccad 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -26,69 +26,125 @@ OUString sNoAlt("No alt text for graphic '%OBJECT_NAME%'");
 OUString sTableMergeSplit("Table '%OBJECT_NAME%' contains merges or splits");
 }
 
-void AccessibilityCheck::checkTableNode(SwTableNode* pTableNode)
+class NodeCheck
 {
-    if (!pTableNode)
-        return;
+protected:
+    std::vector<svx::AccessibilityCheckResult>& m_rAccessibilityCheckResultCollection;
+
+public:
+    NodeCheck(std::vector<svx::AccessibilityCheckResult>& rAccessibilityCheckResultCollection)
+        : m_rAccessibilityCheckResultCollection(rAccessibilityCheckResultCollection)
+    {
+    }
+    virtual ~NodeCheck() {}
+    virtual void check(SwNode* pCurrent) = 0;
+};
+
+// Check NoTextNodes: Graphic, OLE for alt (title) text
+class NoTextNodeAltTextCheck : public NodeCheck
+{
+    void checkNoTextNode(SwNoTextNode* pNoTextNode)
+    {
+        if (!pNoTextNode)
+            return;
+
+        OUString sAlternative = pNoTextNode->GetTitle();
+        if (sAlternative.isEmpty())
+        {
+            OUString sName = pNoTextNode->GetFlyFormat()->GetName();
+            svx::AccessibilityCheckResult aResult;
+            aResult.m_aIssueText = sNoAlt.replaceAll("%OBJECT_NAME%", sName);
+            m_rAccessibilityCheckResultCollection.push_back(aResult);
+        }
+    }
 
-    SwTable const& rTable = pTableNode->GetTable();
-    if (rTable.IsTableComplex())
+public:
+    NoTextNodeAltTextCheck(
+        std::vector<svx::AccessibilityCheckResult>& rAccessibilityCheckResultCollection)
+        : NodeCheck(rAccessibilityCheckResultCollection)
     {
-        OUString sName = rTable.GetTableStyleName();
-        svx::AccessibilityCheckResult aResult;
-        aResult.m_aIssueText = sTableMergeSplit.replaceAll("%OBJECT_NAME%", sName);
-        m_aAccessibilityCheckResultCollection.push_back(aResult);
     }
-    else
+
+    void check(SwNode* pCurrent) override
     {
-        if (rTable.GetTabLines().size() > 1)
+        if (pCurrent->GetNodeType() & SwNodeType::NoTextMask)
         {
-            int i = 0;
-            size_t nFirstLineSize = 0;
-            bool bAllColumnsSameSize = true;
+            SwNoTextNode* pNoTextNode = pCurrent->GetNoTextNode();
+            if (pNoTextNode)
+                checkNoTextNode(pNoTextNode);
+        }
+    }
+};
 
-            for (SwTableLine const* pTableLine : rTable.GetTabLines())
+// Check Table node if the table is merged and splitted.
+class TableNodeMergeSplitCheck : public NodeCheck
+{
+private:
+    void checkTableNode(SwTableNode* pTableNode)
+    {
+        if (!pTableNode)
+            return;
+
+        SwTable const& rTable = pTableNode->GetTable();
+        if (rTable.IsTableComplex())
+        {
+            OUString sName = rTable.GetTableStyleName();
+            svx::AccessibilityCheckResult aResult;
+            aResult.m_aIssueText = sTableMergeSplit.replaceAll("%OBJECT_NAME%", sName);
+            m_rAccessibilityCheckResultCollection.push_back(aResult);
+        }
+        else
+        {
+            if (rTable.GetTabLines().size() > 1)
             {
-                if (i == 0)
-                {
-                    nFirstLineSize = pTableLine->GetTabBoxes().size();
-                }
-                else
+                int i = 0;
+                size_t nFirstLineSize = 0;
+                bool bAllColumnsSameSize = true;
+
+                for (SwTableLine const* pTableLine : rTable.GetTabLines())
                 {
-                    size_t nLineSize = pTableLine->GetTabBoxes().size();
-                    if (nFirstLineSize != nLineSize)
+                    if (i == 0)
                     {
-                        bAllColumnsSameSize = false;
+                        nFirstLineSize = pTableLine->GetTabBoxes().size();
                     }
+                    else
+                    {
+                        size_t nLineSize = pTableLine->GetTabBoxes().size();
+                        if (nFirstLineSize != nLineSize)
+                        {
+                            bAllColumnsSameSize = false;
+                        }
+                    }
+                    i++;
+                }
+                if (!bAllColumnsSameSize)
+                {
+                    OUString sName = rTable.GetTableStyleName();
+                    svx::AccessibilityCheckResult aResult;
+                    aResult.m_aIssueText = sTableMergeSplit.replaceAll("%OBJECT_NAME%", sName);
+                    m_rAccessibilityCheckResultCollection.push_back(aResult);
                 }
-                i++;
-            }
-            if (!bAllColumnsSameSize)
-            {
-                OUString sName = rTable.GetTableStyleName();
-                svx::AccessibilityCheckResult aResult;
-                aResult.m_aIssueText = sTableMergeSplit.replaceAll("%OBJECT_NAME%", sName);
-                m_aAccessibilityCheckResultCollection.push_back(aResult);
             }
         }
     }
-}
 
-// Check NoTextNodes: Graphic, OLE
-void AccessibilityCheck::checkNoTextNode(SwNoTextNode* pNoTextNode)
-{
-    if (!pNoTextNode)
-        return;
+public:
+    TableNodeMergeSplitCheck(
+        std::vector<svx::AccessibilityCheckResult>& rAccessibilityCheckResultCollection)
+        : NodeCheck(rAccessibilityCheckResultCollection)
+    {
+    }
 
-    OUString sAlternative = pNoTextNode->GetTitle();
-    if (sAlternative.isEmpty())
+    void check(SwNode* pCurrent) override
     {
-        OUString sName = pNoTextNode->GetFlyFormat()->GetName();
-        svx::AccessibilityCheckResult aResult;
-        aResult.m_aIssueText = sNoAlt.replaceAll("%OBJECT_NAME%", sName);
-        m_aAccessibilityCheckResultCollection.push_back(aResult);
+        if (pCurrent->GetNodeType() & SwNodeType::Table)
+        {
+            SwTableNode* pTableNode = pCurrent->GetTableNode();
+            if (pTableNode)
+                checkTableNode(pTableNode);
+        }
     }
-}
+};
 
 // Check Shapes, TextBox
 void AccessibilityCheck::checkObject(SdrObject* pObject)
@@ -114,23 +170,22 @@ void AccessibilityCheck::check()
     if (m_pDoc == nullptr)
         return;
 
+    std::vector<std::unique_ptr<NodeCheck>> aNodeChecks;
+    aNodeChecks.push_back(
+        std::make_unique<NoTextNodeAltTextCheck>(m_aAccessibilityCheckResultCollection));
+    aNodeChecks.push_back(
+        std::make_unique<TableNodeMergeSplitCheck>(m_aAccessibilityCheckResultCollection));
+
     auto const& pNodes = m_pDoc->GetNodes();
+    SwNode* pNode = nullptr;
     for (sal_uLong n = 0; n < pNodes.Count(); ++n)
     {
-        SwNode* pNode = pNodes[n];
+        pNode = pNodes[n];
         if (pNode)
         {
-            if (pNode->GetNodeType() & SwNodeType::NoTextMask)
-            {
-                SwNoTextNode* pNoTextNode = pNode->GetNoTextNode();
-                if (pNoTextNode)
-                    checkNoTextNode(pNoTextNode);
-            }
-            if (pNode->GetNodeType() & SwNodeType::Table)
+            for (std::unique_ptr<NodeCheck>& rpNodeCheck : aNodeChecks)
             {
-                SwTableNode* pTableNode = pNode->GetTableNode();
-                if (pTableNode)
-                    checkTableNode(pTableNode);
+                rpNodeCheck->check(pNode);
             }
         }
     }
diff --git a/sw/source/core/inc/AccessibilityCheck.hxx b/sw/source/core/inc/AccessibilityCheck.hxx
index 513e862e7e6f..9e77ca15e125 100644
--- a/sw/source/core/inc/AccessibilityCheck.hxx
+++ b/sw/source/core/inc/AccessibilityCheck.hxx
@@ -13,7 +13,6 @@
 
 #include <svx/AccessibilityCheck.hxx>
 #include <doc.hxx>
-#include <node.hxx>
 
 namespace sw
 {
@@ -29,9 +28,6 @@ public:
     }
 
     void check() override;
-
-    void checkTableNode(SwTableNode* pTableNode);
-    void checkNoTextNode(SwNoTextNode* pNoTextNode);
     void checkObject(SdrObject* pObject);
 };
 
commit 64a2d05f2805714dbe752abe56c5effd55143aee
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Dec 8 12:00:49 2019 +0100
Commit:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sun Dec 8 12:00:49 2019 +0100

    AccessibilityCheck iface, namespaces, move AccessibilitCheckResult
    
    This adds AccessibilityCheck interface into svx, which also
    requires addition of namespaces as there is now AccessibilityCheck
    interface and the implementation in sw (sw::AccessibilityCheck).
    
    As the AccessibilityCheck requires AccessibilitCheckResult, move
    that into svx too.
    
    Change-Id: If7065cdab90b02478c57f22afb7ca716d70b8dce

diff --git a/include/svx/AccessibilityCheck.hxx b/include/svx/AccessibilityCheck.hxx
new file mode 100644
index 000000000000..de240906697a
--- /dev/null
+++ b/include/svx/AccessibilityCheck.hxx
@@ -0,0 +1,46 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef INCLUDED_SVX_ACCESSIBILITYCHECK_HXX
+#define INCLUDED_SVX_ACCESSIBILITYCHECK_HXX
+
+#include <vector>
+#include <rtl/ustring.hxx>
+#include <svx/svxdllapi.h>
+
+namespace svx
+{
+class SVX_DLLPUBLIC AccessibilityCheckResult final
+{
+public:
+    OUString m_aIssueText;
+};
+
+class SVX_DLLPUBLIC AccessibilityCheck
+{
+protected:
+    std::vector<AccessibilityCheckResult> m_aAccessibilityCheckResultCollection;
+
+public:
+    virtual ~AccessibilityCheck() {}
+
+    virtual void check() = 0;
+
+    std::vector<AccessibilityCheckResult> const& getResultCollecton()
+    {
+        return m_aAccessibilityCheckResultCollection;
+    }
+};
+
+} // end svx namespace
+
+#endif // INCLUDED_SVX_ACCESSIBILITYCHECKDIALOG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/AccessibilityCheckDialog.hxx b/include/svx/AccessibilityCheckDialog.hxx
index cbfa2ac573f4..d66bf3b887aa 100644
--- a/include/svx/AccessibilityCheckDialog.hxx
+++ b/include/svx/AccessibilityCheckDialog.hxx
@@ -11,18 +11,15 @@
 #ifndef INCLUDED_SVX_ACCESSIBILITYCHECKDIALOG_HXX
 #define INCLUDED_SVX_ACCESSIBILITYCHECKDIALOG_HXX
 
+#include <svx/AccessibilityCheck.hxx>
 #include <sal/types.h>
 #include <svx/svxdllapi.h>
 #include <tools/gen.hxx>
 #include <tools/link.hxx>
 #include <vcl/weld.hxx>
 
-class SVX_DLLPUBLIC AccessibilityCheckResult
+namespace svx
 {
-public:
-    OUString m_aIssueText;
-};
-
 class SVX_DLLPUBLIC AccessibilityCheckEntry final
 {
 private:
@@ -56,6 +53,8 @@ public:
     virtual short run() override;
 };
 
+} // end svx namespace
+
 #endif // INCLUDED_SVX_ACCESSIBILITYCHECKDIALOG_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/dialog/AccessibilityCheckDialog.cxx b/svx/source/dialog/AccessibilityCheckDialog.cxx
index 08fc63eec6f0..e40f2187f445 100644
--- a/svx/source/dialog/AccessibilityCheckDialog.cxx
+++ b/svx/source/dialog/AccessibilityCheckDialog.cxx
@@ -11,6 +11,8 @@
 #include <svx/AccessibilityCheckDialog.hxx>
 #include <vcl/svapp.hxx>
 
+namespace svx
+{
 AccessibilityCheckEntry::AccessibilityCheckEntry(
     weld::Container* pParent, weld::Window* pDialog,
     AccessibilityCheckResult const& rAccessibilityCheckResult)
@@ -50,4 +52,6 @@ short AccessibilityCheckDialog::run()
     return GenericDialogController::run();
 }
 
+} // end svx namespace
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index 2f724d17b102..42c10af26dcd 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -11,13 +11,17 @@
 #include <AccessibilityCheck.hxx>
 #include <ndgrf.hxx>
 #include <ndole.hxx>
+#include <ndtxt.hxx>
 #include <IDocumentDrawModelAccess.hxx>
 #include <drawdoc.hxx>
 #include <svx/svdpage.hxx>
 #include <swtable.hxx>
 
+namespace sw
+{
 namespace
 {
+// TODO move these to string file and look for a better name.
 OUString sNoAlt("No alt text for graphic '%OBJECT_NAME%'");
 OUString sTableMergeSplit("Table '%OBJECT_NAME%' contains merges or splits");
 }
@@ -31,7 +35,7 @@ void AccessibilityCheck::checkTableNode(SwTableNode* pTableNode)
     if (rTable.IsTableComplex())
     {
         OUString sName = rTable.GetTableStyleName();
-        AccessibilityCheckResult aResult;
+        svx::AccessibilityCheckResult aResult;
         aResult.m_aIssueText = sTableMergeSplit.replaceAll("%OBJECT_NAME%", sName);
         m_aAccessibilityCheckResultCollection.push_back(aResult);
     }
@@ -62,7 +66,7 @@ void AccessibilityCheck::checkTableNode(SwTableNode* pTableNode)
             if (!bAllColumnsSameSize)
             {
                 OUString sName = rTable.GetTableStyleName();
-                AccessibilityCheckResult aResult;
+                svx::AccessibilityCheckResult aResult;
                 aResult.m_aIssueText = sTableMergeSplit.replaceAll("%OBJECT_NAME%", sName);
                 m_aAccessibilityCheckResultCollection.push_back(aResult);
             }
@@ -80,7 +84,7 @@ void AccessibilityCheck::checkNoTextNode(SwNoTextNode* pNoTextNode)
     if (sAlternative.isEmpty())
     {
         OUString sName = pNoTextNode->GetFlyFormat()->GetName();
-        AccessibilityCheckResult aResult;
+        svx::AccessibilityCheckResult aResult;
         aResult.m_aIssueText = sNoAlt.replaceAll("%OBJECT_NAME%", sName);
         m_aAccessibilityCheckResultCollection.push_back(aResult);
     }
@@ -98,7 +102,7 @@ void AccessibilityCheck::checkObject(SdrObject* pObject)
         if (sAlternative.isEmpty())
         {
             OUString sName = pObject->GetName();
-            AccessibilityCheckResult aResult;
+            svx::AccessibilityCheckResult aResult;
             aResult.m_aIssueText = sNoAlt.replaceAll("%OBJECT_NAME%", sName);
             m_aAccessibilityCheckResultCollection.push_back(aResult);
         }
@@ -145,4 +149,6 @@ void AccessibilityCheck::check()
     }
 }
 
+} // end sw namespace
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/AccessibilityCheck.hxx b/sw/source/core/inc/AccessibilityCheck.hxx
index 2540b3063be5..513e862e7e6f 100644
--- a/sw/source/core/inc/AccessibilityCheck.hxx
+++ b/sw/source/core/inc/AccessibilityCheck.hxx
@@ -11,14 +11,16 @@
 #ifndef INCLUDED_SW_SOURCE_CORE_ACCESSIBILITYCHECK_HXX
 #define INCLUDED_SW_SOURCE_CORE_ACCESSIBILITYCHECK_HXX
 
-#include <svx/AccessibilityCheckDialog.hxx>
+#include <svx/AccessibilityCheck.hxx>
 #include <doc.hxx>
 #include <node.hxx>
 
-class AccessibilityCheck
+namespace sw
 {
+class AccessibilityCheck final : public svx::AccessibilityCheck
+{
+private:
     SwDoc* m_pDoc;
-    std::vector<AccessibilityCheckResult> m_aAccessibilityCheckResultCollection;
 
 public:
     AccessibilityCheck(SwDoc* pDoc)
@@ -26,17 +28,15 @@ public:
     {
     }
 
-    std::vector<AccessibilityCheckResult> const& getResultCollecton()
-    {
-        return m_aAccessibilityCheckResultCollection;
-    }
+    void check() override;
 
-    void check();
     void checkTableNode(SwTableNode* pTableNode);
     void checkNoTextNode(SwNoTextNode* pNoTextNode);
     void checkObject(SdrObject* pObject);
 };
 
+} // end sw namespace
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index 1360e6a1ca0d..c913193539ae 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -2647,9 +2647,9 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq)
         break;
         case SID_ACCESSIBILITY_CHECK:
         {
-            AccessibilityCheck aCheck(rSh.GetDoc());
+            sw::AccessibilityCheck aCheck(rSh.GetDoc());
             aCheck.check();
-            AccessibilityCheckDialog aDialog(pMDI, aCheck.getResultCollecton());
+            svx::AccessibilityCheckDialog aDialog(pMDI, aCheck.getResultCollecton());
             aDialog.run();
         }
         break;


More information about the Libreoffice-commits mailing list