summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParis Oplopoios <paris.oplopoios@collabora.com>2022-10-17 12:37:30 +0300
committerTomaž Vajngerl <quikee@gmail.com>2022-10-17 16:32:13 +0200
commitf03d285d51ba5d5b30e9f8a2b1165270140d5a20 (patch)
tree8edf8f4b325d8af6301f309980a8ea5e60d0a672
parentcbe2d304e1ab33fae8e7b0c72dccbaa576ee5184 (diff)
a11y: Add check for spacing newlines
Add accessibility check and relevant test for a document that uses newlines for spacing Change-Id: I14f14db5c51cbad1ee184e58eec8ff28563ba92a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141252 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r--sw/inc/AccessibilityCheckStrings.hrc1
-rw-r--r--sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx12
-rw-r--r--sw/qa/core/accessibilitycheck/data/AccessibilityTests1.odtbin20915 -> 19334 bytes
-rw-r--r--sw/qa/core/accessibilitycheck/data/NewlineTest.odtbin0 -> 8609 bytes
-rw-r--r--sw/source/core/access/AccessibilityCheck.cxx87
5 files changed, 100 insertions, 0 deletions
diff --git a/sw/inc/AccessibilityCheckStrings.hrc b/sw/inc/AccessibilityCheckStrings.hrc
index 858de1a47d93..4d65bd095f51 100644
--- a/sw/inc/AccessibilityCheckStrings.hrc
+++ b/sw/inc/AccessibilityCheckStrings.hrc
@@ -22,6 +22,7 @@
#define STR_AVOID_FOOTNOTES NC_("STR_AVOID_FOOTNOTES", "Avoid footnotes.")
#define STR_AVOID_ENDNOTES NC_("STR_AVOID_ENDNOTES", "Avoid endnotes.")
#define STR_AVOID_BACKGROUND_IMAGES NC_("STR_AVOID_BACKGROUND_IMAGES", "Avoid background images.")
+#define STR_AVOID_NEWLINES_SPACE NC_("STR_AVOID_NEWLINES_SPACE", "Avoid newlines to create space.")
#define STR_HEADINGS_NOT_IN_ORDER NC_("STR_HEADINGS_NOT_IN_ORDER", "Headings not in order.")
#define STR_TEXT_FORMATTING_CONVEYS_MEANING NC_("STR_TEXT_FORMATTING_CONVEYS_MEANING", "The text formatting conveys additional meaning.")
#define STR_NON_INTERACTIVE_FORMS NC_("STR_NON_INTERACTIVE_FORMS", "An input form is not interactive.")
diff --git a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
index 2c36d2b5d4e7..7a60b1578e21 100644
--- a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
+++ b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
@@ -70,6 +70,18 @@ CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testCheckBackgroundImage)
CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND, aIssues[0]->m_eIssueID);
}
+CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testCheckNewlineSpace)
+{
+ SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "NewlineTest.odt");
+ CPPUNIT_ASSERT(pDoc);
+ sw::AccessibilityCheck aCheck(pDoc);
+ aCheck.check();
+ auto& aIssues = aCheck.getIssueCollection().getIssues();
+ CPPUNIT_ASSERT_EQUAL(size_t(2), aIssues.size());
+ CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[0]->m_eIssueID);
+ CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[1]->m_eIssueID);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/accessibilitycheck/data/AccessibilityTests1.odt b/sw/qa/core/accessibilitycheck/data/AccessibilityTests1.odt
index 2e319f58e7a2..6b55335e773d 100644
--- a/sw/qa/core/accessibilitycheck/data/AccessibilityTests1.odt
+++ b/sw/qa/core/accessibilitycheck/data/AccessibilityTests1.odt
Binary files differ
diff --git a/sw/qa/core/accessibilitycheck/data/NewlineTest.odt b/sw/qa/core/accessibilitycheck/data/NewlineTest.odt
new file mode 100644
index 000000000000..9ff715916fc2
--- /dev/null
+++ b/sw/qa/core/accessibilitycheck/data/NewlineTest.odt
Binary files differ
diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index de0a5bf63472..f56bdf3e0c7b 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -584,6 +584,92 @@ public:
}
};
+class NewlineSpacingCheck : public NodeCheck
+{
+private:
+ static SwTextNode* getNextTextNode(SwNode* pCurrent)
+ {
+ SwTextNode* pTextNode = nullptr;
+
+ auto nIndex = pCurrent->GetIndex();
+ auto nCount = pCurrent->GetNodes().Count();
+
+ nIndex++; // go to next node
+
+ while (pTextNode == nullptr && nIndex < nCount)
+ {
+ auto pNode = pCurrent->GetNodes()[nIndex];
+ if (pNode->IsTextNode())
+ pTextNode = pNode->GetTextNode();
+ nIndex++;
+ }
+
+ return pTextNode;
+ }
+
+public:
+ NewlineSpacingCheck(sfx::AccessibilityIssueCollection& rIssueCollection)
+ : NodeCheck(rIssueCollection)
+ {
+ }
+ void check(SwNode* pCurrent) override
+ {
+ if (!pCurrent->IsTextNode())
+ return;
+
+ SwTextNode* pTextNode = pCurrent->GetTextNode();
+ auto nParagraphLength = pTextNode->GetText().getLength();
+ if (nParagraphLength == 0)
+ {
+ SwTextNode* pNextTextNode = getNextTextNode(pCurrent);
+ if (!pNextTextNode)
+ return;
+ if (pNextTextNode->GetText().getLength() == 0)
+ {
+ auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_AVOID_NEWLINES_SPACE),
+ sfx::AccessibilityIssueID::TEXT_FORMATTING);
+ pIssue->setIssueObject(IssueObject::TEXT);
+ pIssue->setNode(pNextTextNode);
+ SwDoc& rDocument = pNextTextNode->GetDoc();
+ pIssue->setDoc(rDocument);
+ }
+ }
+ else
+ {
+ // Check for excess lines inside this paragraph
+ const OUString& sParagraphText = pTextNode->GetText();
+ int nLineCount = 0;
+ for (sal_Int32 i = 0; i < nParagraphLength; i++)
+ {
+ auto aChar = sParagraphText[i];
+ if (aChar == '\n')
+ {
+ nLineCount++;
+ // Looking for 2 newline characters and above as one can be part of the line
+ // break after a sentence
+ if (nLineCount > 2)
+ {
+ auto pIssue
+ = lclAddIssue(m_rIssueCollection, SwResId(STR_AVOID_NEWLINES_SPACE),
+ sfx::AccessibilityIssueID::TEXT_FORMATTING);
+ pIssue->setIssueObject(IssueObject::TEXT);
+ pIssue->setNode(pTextNode);
+ SwDoc& rDocument = pTextNode->GetDoc();
+ pIssue->setDoc(rDocument);
+ pIssue->setStart(i);
+ pIssue->setEnd(i);
+ }
+ }
+ // Don't count carriage return as normal character
+ else if (aChar != '\r')
+ {
+ nLineCount = 0;
+ }
+ }
+ }
+ }
+};
+
class BlinkingTextCheck : public NodeCheck
{
private:
@@ -1006,6 +1092,7 @@ void AccessibilityCheck::check()
aNodeChecks.push_back(std::make_unique<FloatingTextCheck>(m_aIssueCollection));
aNodeChecks.push_back(std::make_unique<TableHeadingCheck>(m_aIssueCollection));
aNodeChecks.push_back(std::make_unique<HeadingOrderCheck>(m_aIssueCollection));
+ aNodeChecks.push_back(std::make_unique<NewlineSpacingCheck>(m_aIssueCollection));
auto const& pNodes = m_pDoc->GetNodes();
SwNode* pNode = nullptr;