include/sfx2/AccessibilityIssue.hxx                        |    1 
 sw/inc/AccessibilityCheckStrings.hrc                       |    1 
 sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx   |   11 ++
 sw/qa/core/accessibilitycheck/data/TableFormattingTest.odt |binary
 sw/source/core/access/AccessibilityCheck.cxx               |   49 +++++++++++++
 5 files changed, 62 insertions(+)

New commits:
commit 5c8934809ac60488d6160e27ff5962350c612a09
Author:     Paris Oplopoios <paris.oplopo...@collabora.com>
AuthorDate: Thu Nov 3 01:02:40 2022 +0200
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Thu Nov 3 07:53:53 2022 +0100

    a11y: Add check for table used for text formatting
    
    Add accessibility check and relevant test for a document that uses a
    table for text formatting
    
    Change-Id: I20290a3ec89cd5333f3c66867b50aa7b80ed494f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142188
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/include/sfx2/AccessibilityIssue.hxx 
b/include/sfx2/AccessibilityIssue.hxx
index b9e3266c73a2..0c22d9e19238 100644
--- a/include/sfx2/AccessibilityIssue.hxx
+++ b/include/sfx2/AccessibilityIssue.hxx
@@ -29,6 +29,7 @@ enum class AccessibilityIssueID
     NO_ALT_SHAPE,
     TABLE_MERGE_SPLIT,
     TEXT_FORMATTING,
+    TABLE_FORMATTING,
     HYPERLINK_IS_TEXT,
     HYPERLINK_SHORT,
     FAKE_FOOTNOTE,
diff --git a/sw/inc/AccessibilityCheckStrings.hrc 
b/sw/inc/AccessibilityCheckStrings.hrc
index e63d304d1063..7245a2b8d3e0 100644
--- a/sw/inc/AccessibilityCheckStrings.hrc
+++ b/sw/inc/AccessibilityCheckStrings.hrc
@@ -34,6 +34,7 @@
 #define STR_HEADING_IN_TABLE            NC_("STR_HEADING_IN_TABLE", "Tables 
must not contain headings.")
 #define STR_HEADING_ORDER               NC_("STR_HEADING_ORDER", "Keep 
headings' levels ordered. Heading level %LEVEL_CURRENT% must not go after 
%LEVEL_PREV%.")
 #define STR_FONTWORKS                   NC_("STR_FONTWORKS", "Avoid Fontwork 
objects in your documents. Make sure you use it for samples or other 
meaningless text.")
+#define STR_TABLE_FORMATTING            NC_("STR_TABLE_FORMATTING", "Avoid 
using empty table cells for formatting.")
 
 #define STR_DOCUMENT_DEFAULT_LANGUAGE   NC_("STR_DOCUMENT_DEFAULT_LANGUAGE", 
"Document default language is not set")
 #define STR_STYLE_NO_LANGUAGE           NC_("STR_STYLE_NO_LANGUAGE", "Style 
'%STYLE_NAME%' has no language set")
diff --git a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx 
b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
index 02912e4c9d35..b7561ad01764 100644
--- a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
+++ b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
@@ -154,6 +154,17 @@ CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, 
testCheckFakeCaption)
     CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::FAKE_CAPTION, 
aIssues[0]->m_eIssueID);
 }
 
+CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testCheckTableFormatting)
+{
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "TableFormattingTest.odt");
+    CPPUNIT_ASSERT(pDoc);
+    sw::AccessibilityCheck aCheck(pDoc);
+    aCheck.check();
+    auto& aIssues = aCheck.getIssueCollection().getIssues();
+    CPPUNIT_ASSERT_EQUAL(size_t(1), aIssues.size());
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TABLE_FORMATTING, 
aIssues[0]->m_eIssueID);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/accessibilitycheck/data/TableFormattingTest.odt 
b/sw/qa/core/accessibilitycheck/data/TableFormattingTest.odt
new file mode 100644
index 000000000000..adc63daaf7cb
Binary files /dev/null and 
b/sw/qa/core/accessibilitycheck/data/TableFormattingTest.odt differ
diff --git a/sw/source/core/access/AccessibilityCheck.cxx 
b/sw/source/core/access/AccessibilityCheck.cxx
index 0170003c4a48..ce0409d6ba5b 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -236,6 +236,50 @@ public:
     }
 };
 
+class TableFormattingCheck : public NodeCheck
+{
+private:
+    void checkTableNode(SwTableNode* pTableNode)
+    {
+        if (!pTableNode)
+            return;
+
+        const SwTable& rTable = pTableNode->GetTable();
+        if (!rTable.IsTableComplex())
+        {
+            size_t nEmptyBoxes = 0;
+            size_t nBoxCount = 0;
+            for (const SwTableLine* pTableLine : rTable.GetTabLines())
+            {
+                nBoxCount += pTableLine->GetTabBoxes().size();
+                for (const SwTableBox* pBox : pTableLine->GetTabBoxes())
+                    if (pBox->IsEmpty())
+                        ++nEmptyBoxes;
+            }
+            // If more than half of the boxes are empty we can assume that it 
is used for formatting
+            if (nEmptyBoxes > nBoxCount / 2)
+                lclAddIssue(m_rIssueCollection, SwResId(STR_TABLE_FORMATTING),
+                            sfx::AccessibilityIssueID::TABLE_FORMATTING);
+        }
+    }
+
+public:
+    TableFormattingCheck(sfx::AccessibilityIssueCollection& rIssueCollection)
+        : NodeCheck(rIssueCollection)
+    {
+    }
+
+    void check(SwNode* pCurrent) override
+    {
+        if (pCurrent->GetNodeType() & SwNodeType::Table)
+        {
+            SwTableNode* pTableNode = pCurrent->GetTableNode();
+            if (pTableNode)
+                checkTableNode(pTableNode);
+        }
+    }
+};
+
 class NumberingCheck : public NodeCheck
 {
 private:
@@ -674,6 +718,10 @@ public:
         if (!pCurrent->IsTextNode())
             return;
 
+        // Don't count empty table box text nodes
+        if (pCurrent->GetTableBox())
+            return;
+
         SwTextNode* pTextNode = pCurrent->GetTextNode();
         auto nParagraphLength = pTextNode->GetText().getLength();
         if (nParagraphLength == 0)
@@ -1318,6 +1366,7 @@ void AccessibilityCheck::check()
     std::vector<std::unique_ptr<NodeCheck>> aNodeChecks;
     
aNodeChecks.push_back(std::make_unique<NoTextNodeAltTextCheck>(m_aIssueCollection));
     
aNodeChecks.push_back(std::make_unique<TableNodeMergeSplitCheck>(m_aIssueCollection));
+    
aNodeChecks.push_back(std::make_unique<TableFormattingCheck>(m_aIssueCollection));
     
aNodeChecks.push_back(std::make_unique<NumberingCheck>(m_aIssueCollection));
     
aNodeChecks.push_back(std::make_unique<HyperlinkCheck>(m_aIssueCollection));
     
aNodeChecks.push_back(std::make_unique<TextContrastCheck>(m_aIssueCollection));

Reply via email to