sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx | 58 + sw/qa/core/accessibilitycheck/data/DeleteHeader.odt |binary sw/qa/core/accessibilitycheck/data/PageCharParaStyles.odt |binary sw/source/core/access/AccessibilityCheck.cxx | 763 ++++++++++++-- translations | 2 5 files changed, 747 insertions(+), 76 deletions(-)
New commits: commit 85d7d20444b0eee9a542846f06eff8813811e3a6 Author: Balazs Varga <[email protected]> AuthorDate: Fri Sep 13 10:24:38 2024 +0200 Commit: Thorsten Behrens <[email protected]> CommitDate: Tue Sep 17 14:51:07 2024 +0200 tdf#162890 - A11Y sidebar: fix unecceserry warning in case if we have no any direct format or we have a style which are not applied to the page. (In that case no need to show the warning since the 'goto' can lead us nowhere.) Also check the direct formats by comparing them to the character styles, paragraph styles or to the default character properties. Change-Id: I154379dc6deaa3af3fe17e51367cc229067216dd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173317 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <[email protected]> diff --git a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx index 621a811def50..f45d4356be3b 100644 --- a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx +++ b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx @@ -269,6 +269,24 @@ CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testDeleteHeader) CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aResultIssues[2]->m_eIssueID); } +CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testStylesWithHeader) +{ + // Check direct formats, char/para styles and not allowed page styles + createSwDoc("PageCharParaStyles.odt"); + SwDoc* pDoc = getSwDoc(); + CPPUNIT_ASSERT(pDoc); + + sw::AccessibilityCheck aCheck(pDoc); + auto& aIssues = aCheck.getIssueCollection().getIssues(); + aCheck.check(); + CPPUNIT_ASSERT_EQUAL(size_t(5), aIssues.size()); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DOCUMENT_TITLE, aIssues[0]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[1]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[2]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[3]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[4]->m_eIssueID); +} + namespace { std::vector<std::shared_ptr<sfx::AccessibilityIssue>> diff --git a/sw/qa/core/accessibilitycheck/data/PageCharParaStyles.odt b/sw/qa/core/accessibilitycheck/data/PageCharParaStyles.odt new file mode 100644 index 000000000000..2f073a4a4afb Binary files /dev/null and b/sw/qa/core/accessibilitycheck/data/PageCharParaStyles.odt differ diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx index 362279f219ae..83ff5de88ff1 100644 --- a/sw/source/core/access/AccessibilityCheck.cxx +++ b/sw/source/core/access/AccessibilityCheck.cxx @@ -639,11 +639,22 @@ public: { } - void checkAutoFormat(SwTextNode* pTextNode, const SwTextAttr* pTextAttr) + void checkAutoFormat(SwTextNode* pTextNode, const SwTextAttr* pTextAttr, + const std::map<sal_Int32, const SwTextAttr*>& rCharFormats) { const SwFormatAutoFormat& rAutoFormat = pTextAttr->GetAutoFormat(); SfxItemIter aItemIter(*rAutoFormat.GetStyleHandle()); const SfxPoolItem* pItem = aItemIter.GetCurItem(); + + const SwTextAttr* pCharAttr = nullptr; + auto itr = rCharFormats.find(pTextAttr->GetStart()); + if (itr != rCharFormats.end()) + pCharAttr = itr->second; + + const SwCharFormat* pCharformat = nullptr; + if (pCharAttr && (*pTextAttr->GetEnd() == *pCharAttr->GetEnd())) + pCharformat = pCharAttr->GetCharFormat().GetCharFormat(); + std::vector<OUString> aFormattings; while (pItem) { @@ -653,57 +664,367 @@ public: case RES_CHRATR_WEIGHT: case RES_CHRATR_CJK_WEIGHT: case RES_CHRATR_CTL_WEIGHT: - sFormattingType = "Weight"; - break; + { + const SvxWeightItem* pStyleItem = nullptr; + + if (pCharformat) + { + pStyleItem = pCharformat->GetItemIfSet( + TypedWhichId<SvxWeightItem>(pItem->Which()), false); + } + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + TypedWhichId<SvxWeightItem>(pItem->Which()), false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + TypedWhichId<SvxWeightItem>(pItem->Which())); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxWeightItem*>(pItem), pStyleItem)) + sFormattingType = "Weight"; + } + break; + case RES_CHRATR_POSTURE: case RES_CHRATR_CJK_POSTURE: case RES_CHRATR_CTL_POSTURE: - sFormattingType = "Posture"; - break; + { + const SvxPostureItem* pStyleItem = nullptr; + + if (pCharformat) + { + pStyleItem = pCharformat->GetItemIfSet( + TypedWhichId<SvxPostureItem>(pItem->Which()), false); + } + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + TypedWhichId<SvxPostureItem>(pItem->Which()), false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + TypedWhichId<SvxPostureItem>(pItem->Which())); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxPostureItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Posture"; + } + } + break; case RES_CHRATR_SHADOWED: - sFormattingType = "Shadowed"; - break; + { + const SvxShadowedItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_SHADOWED, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_SHADOWED, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_SHADOWED); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxShadowedItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Shadowed"; + } + } + break; case RES_CHRATR_COLOR: - sFormattingType = "Font Color"; - break; + { + const SvxColorItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_COLOR, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_COLOR, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_COLOR); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxColorItem*>(pItem), pStyleItem)) + sFormattingType = "Font Color"; + } + break; case RES_CHRATR_FONTSIZE: - case RES_CHRATR_CJK_FONTSIZE: - case RES_CHRATR_CTL_FONTSIZE: - sFormattingType = "Font Size"; - break; + { + // case RES_CHRATR_CJK_FONTSIZE: + // case RES_CHRATR_CTL_FONTSIZE: + // TODO: check depending on which lang is used Western, Complex, Asia + const SvxFontHeightItem* pStyleItem = nullptr; + + if (pCharformat) + { + pStyleItem = pCharformat->GetItemIfSet( + TypedWhichId<SvxFontHeightItem>(pItem->Which()), false); + } + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + TypedWhichId<SvxFontHeightItem>(pItem->Which()), false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + TypedWhichId<SvxFontHeightItem>(pItem->Which())); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxFontHeightItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Font Size"; + } + } + break; case RES_CHRATR_FONT: case RES_CHRATR_CJK_FONT: case RES_CHRATR_CTL_FONT: - sFormattingType = "Font"; - break; + { + // 3. direct formatting + const SvxFontItem* pStyleItem = nullptr; + + if (pCharformat) + { + pStyleItem = pCharformat->GetItemIfSet( + TypedWhichId<SvxFontItem>(pItem->Which()), false); + } + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + TypedWhichId<SvxFontItem>(pItem->Which()), false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + TypedWhichId<SvxFontItem>(pItem->Which())); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxFontItem*>(pItem), pStyleItem)) + sFormattingType = "Font"; + } + break; case RES_CHRATR_EMPHASIS_MARK: - sFormattingType = "Emphasis Mark"; - break; + { + const SvxEmphasisMarkItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_EMPHASIS_MARK, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + RES_CHRATR_EMPHASIS_MARK, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_EMPHASIS_MARK); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxEmphasisMarkItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Emphasis Mark"; + } + } + break; case RES_CHRATR_UNDERLINE: - sFormattingType = "Underline"; - break; + { + const SvxUnderlineItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_UNDERLINE, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_UNDERLINE, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_UNDERLINE); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxUnderlineItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Underline"; + } + } + break; case RES_CHRATR_OVERLINE: - sFormattingType = "Overline"; - break; + { + const SvxOverlineItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_OVERLINE, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_OVERLINE, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_OVERLINE); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxOverlineItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Overline"; + } + } + break; case RES_CHRATR_CROSSEDOUT: - sFormattingType = "Strikethrough"; - break; + { + const SvxCrossedOutItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_CROSSEDOUT, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_CROSSEDOUT, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_CROSSEDOUT); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxCrossedOutItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Strikethrough"; + } + } + break; case RES_CHRATR_RELIEF: - sFormattingType = "Relief"; - break; + { + const SvxCharReliefItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_RELIEF, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_RELIEF, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_RELIEF); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxCharReliefItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Relief"; + } + } + break; case RES_CHRATR_CONTOUR: - sFormattingType = "Outline"; - break; + { + const SvxContourItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_CONTOUR, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_CONTOUR, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_CONTOUR); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxContourItem*>(pItem), + pStyleItem)) + { + sFormattingType = "Outline"; + } + } + break; + + case RES_CHRATR_NOHYPHEN: + { + const SvxNoHyphenItem* pStyleItem = nullptr; + + if (pCharformat) + pStyleItem = pCharformat->GetItemIfSet(RES_CHRATR_NOHYPHEN, false); + + if (!pStyleItem && pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_NOHYPHEN, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_NOHYPHEN); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxNoHyphenItem*>(pItem), + pStyleItem)) + { + sFormattingType = "No Hyphenation"; + } + } + break; + default: break; } @@ -725,45 +1046,328 @@ public: pIssue->setEnd(pTextAttr->GetAnyEnd()); } + static bool isDirectFormat(const SwTextNode* pTextNode, const SwAttrSet& rSwAttrSet) + { + const SfxPoolItem* pItem = nullptr; + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_WEIGHT, false)) + || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CJK_WEIGHT, false)) + || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CTL_WEIGHT, false))) + { + // 3. direct formatting + const SvxWeightItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + { + // 1. paragraph format + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + TypedWhichId<SvxWeightItem>(pItem->Which()), false); + } + + if (!pStyleItem) + { + // 0. document default + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + TypedWhichId<SvxWeightItem>(pItem->Which())); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxWeightItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_POSTURE, false)) + || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CJK_POSTURE, false)) + || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CTL_POSTURE, false))) + { + const SvxPostureItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + { + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + TypedWhichId<SvxPostureItem>(pItem->Which()), false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + TypedWhichId<SvxPostureItem>(pItem->Which())); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxPostureItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_SHADOWED, false))) + { + const SvxShadowedItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_SHADOWED, false); + + if (!pStyleItem) + { + pStyleItem + = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_SHADOWED); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxShadowedItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_COLOR, false))) + { + const SvxColorItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_COLOR, false); + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_COLOR); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxColorItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + // TODO: check depending on which lang is used Western, Complex, Asia + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_FONTSIZE, false)) + /*|| (pItem = rSwAttrSet.GetItem(RES_CHRATR_CJK_FONTSIZE, false)) + || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CTL_FONTSIZE, false))*/) + { + const SvxFontHeightItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + { + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + TypedWhichId<SvxFontHeightItem>(pItem->Which()), false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + TypedWhichId<SvxFontHeightItem>(pItem->Which())); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxFontHeightItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_FONT, false)) + || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CJK_FONT, false)) + || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CTL_FONT, false))) + { + const SvxFontItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + { + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet( + TypedWhichId<SvxFontItem>(pItem->Which()), false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + TypedWhichId<SvxFontItem>(pItem->Which())); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxFontItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_EMPHASIS_MARK, false))) + { + const SvxEmphasisMarkItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + { + pStyleItem + = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_EMPHASIS_MARK, false); + } + + if (!pStyleItem) + { + pStyleItem = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem( + RES_CHRATR_EMPHASIS_MARK); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxEmphasisMarkItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_UNDERLINE, false))) + { + const SvxUnderlineItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_UNDERLINE, false); + + if (!pStyleItem) + { + pStyleItem + = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_UNDERLINE); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxUnderlineItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_OVERLINE, false))) + { + const SvxOverlineItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_OVERLINE, false); + + if (!pStyleItem) + { + pStyleItem + = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_OVERLINE); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxOverlineItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_CROSSEDOUT, false))) + { + const SvxCrossedOutItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_CROSSEDOUT, false); + + if (!pStyleItem) + { + pStyleItem + = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_CROSSEDOUT); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxCrossedOutItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_RELIEF, false))) + { + const SvxCharReliefItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_RELIEF, false); + + if (!pStyleItem) + { + pStyleItem + = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_RELIEF); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxCharReliefItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_NOHYPHEN, false))) + { + const SvxNoHyphenItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_NOHYPHEN, false); + + if (!pStyleItem) + { + pStyleItem + = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_NOHYPHEN); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxNoHyphenItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_CONTOUR, false))) + { + const SvxContourItem* pStyleItem = nullptr; + + if (pTextNode->GetTextColl()) + pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_CONTOUR, false); + + if (!pStyleItem) + { + pStyleItem + = pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_CONTOUR); + } + + if (!SfxPoolItem::areSame(static_cast<const SvxContourItem*>(pItem), pStyleItem)) + return true; + else + pItem = nullptr; + } + + return false; + } + void check(SwNode* pCurrent) override { if (!pCurrent->IsTextNode()) return; SwTextNode* pTextNode = pCurrent->GetTextNode(); + SwWrtShell* pWrtShell = pTextNode->GetDoc().GetDocShell()->GetWrtShell(); + if (pWrtShell && !pTextNode->getLayoutFrame(pWrtShell->GetLayout())) + return; + if (pTextNode->HasHints()) { + // collect character style formats (if have) SwpHints& rHints = pTextNode->GetSwpHints(); + std::map<sal_Int32, const SwTextAttr*> aCharFormats; + for (size_t i = 0; i < rHints.Count(); ++i) + { + const SwTextAttr* pTextAttr = rHints.Get(i); + + if (pTextAttr->Which() == RES_TXTATR_CHARFMT) + { + aCharFormats.insert({ pTextAttr->GetStart(), pTextAttr }); + } + } + + // direct formatting for (size_t i = 0; i < rHints.Count(); ++i) { const SwTextAttr* pTextAttr = rHints.Get(i); if (pTextAttr->Which() == RES_TXTATR_AUTOFMT) { - checkAutoFormat(pTextNode, pTextAttr); + checkAutoFormat(pTextNode, pTextAttr, aCharFormats); } } } - else if (pTextNode->HasSwAttrSet()) + if (pTextNode->HasSwAttrSet()) { // Paragraph doesn't have hints but the entire paragraph might have char attributes - auto& aSwAttrSet = pTextNode->GetSwAttrSet(); auto nParagraphLength = pTextNode->GetText().getLength(); if (nParagraphLength == 0) return; - if (aSwAttrSet.GetItem(RES_CHRATR_WEIGHT, false) - || aSwAttrSet.GetItem(RES_CHRATR_CJK_WEIGHT, false) - || aSwAttrSet.GetItem(RES_CHRATR_CTL_WEIGHT, false) - || aSwAttrSet.GetItem(RES_CHRATR_POSTURE, false) - || aSwAttrSet.GetItem(RES_CHRATR_CJK_POSTURE, false) - || aSwAttrSet.GetItem(RES_CHRATR_CTL_POSTURE, false) - || aSwAttrSet.GetItem(RES_CHRATR_SHADOWED, false) - || aSwAttrSet.GetItem(RES_CHRATR_COLOR, false) - || aSwAttrSet.GetItem(RES_CHRATR_EMPHASIS_MARK, false) - || aSwAttrSet.GetItem(RES_CHRATR_UNDERLINE, false) - || aSwAttrSet.GetItem(RES_CHRATR_OVERLINE, false) - || aSwAttrSet.GetItem(RES_CHRATR_CROSSEDOUT, false) - || aSwAttrSet.GetItem(RES_CHRATR_RELIEF, false) - || aSwAttrSet.GetItem(RES_CHRATR_CONTOUR, false)) + + if (isDirectFormat(pTextNode, pTextNode->GetSwAttrSet())) { auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_TEXT_FORMATTING_CONVEYS_MEANING), commit 8da940e0be4c6da5633b34ea70ba13f3ac048aa0 Author: Balazs Varga <[email protected]> AuthorDate: Wed Sep 11 15:56:36 2024 +0200 Commit: Thorsten Behrens <[email protected]> CommitDate: Tue Sep 17 12:08:55 2024 +0200 tdf#162889 - A11Y sidebar: fix warning does not disappear when page header is deleted. Check if nodes have contentframe. Change-Id: Ie7f79cedb577b856d518d23326e9d7ceba2b825c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173215 Reviewed-by: Michael Stahl <[email protected]> Tested-by: Gabor Kelemen <[email protected]> Reviewed-by: Balazs Varga <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173511 Tested-by: allotropia jenkins <[email protected]> Reviewed-by: Thorsten Behrens <[email protected]> diff --git a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx index bfe2e08d8543..621a811def50 100644 --- a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx +++ b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx @@ -229,6 +229,46 @@ CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testCheckTOCHyperlink) CPPUNIT_ASSERT_EQUAL(size_t(0), aIssues.size()); } +CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testDeleteHeader) +{ + // Delete Header from doc and check if we have less Direct format warning + createSwDoc("DeleteHeader.odt"); + SwDoc* pDoc = getSwDoc(); + CPPUNIT_ASSERT(pDoc); + + sw::AccessibilityCheck aCheck(pDoc); + auto& aIssues = aCheck.getIssueCollection().getIssues(); + aCheck.check(); + CPPUNIT_ASSERT_EQUAL(size_t(8), aIssues.size()); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DOCUMENT_TITLE, aIssues[0]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[1]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[2]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[3]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[4]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[5]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[6]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aIssues[7]->m_eIssueID); + + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + + // modify header + pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false); + pWrtShell->GetWin()->GrabFocusToDocument(); + + // re-check A11Y issues + sw::AccessibilityCheck aReCheck(pDoc); + auto& aResultIssues = aReCheck.getIssueCollection().getIssues(); + aReCheck.check(); + + // Check the result + aResultIssues = aReCheck.getIssueCollection().getIssues(); + CPPUNIT_ASSERT_EQUAL(size_t(3), aResultIssues.size()); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DOCUMENT_TITLE, aResultIssues[0]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aResultIssues[1]->m_eIssueID); + CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, aResultIssues[2]->m_eIssueID); +} + namespace { std::vector<std::shared_ptr<sfx::AccessibilityIssue>> diff --git a/sw/qa/core/accessibilitycheck/data/DeleteHeader.odt b/sw/qa/core/accessibilitycheck/data/DeleteHeader.odt new file mode 100644 index 000000000000..6503699c132b Binary files /dev/null and b/sw/qa/core/accessibilitycheck/data/DeleteHeader.odt differ diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx index dfa94c3ed9ab..362279f219ae 100644 --- a/sw/source/core/access/AccessibilityCheck.cxx +++ b/sw/source/core/access/AccessibilityCheck.cxx @@ -15,6 +15,7 @@ #include <ndnotxt.hxx> #include <ndtxt.hxx> #include <docsh.hxx> +#include <wrtsh.hxx> #include <IDocumentDrawModelAccess.hxx> #include <drawdoc.hxx> #include <svx/svdpage.hxx> @@ -814,52 +815,60 @@ public: return; SwTextNode* pTextNode = pCurrent->GetTextNode(); + SwDoc& rDocument = pTextNode->GetDoc(); auto nParagraphLength = pTextNode->GetText().getLength(); if (nParagraphLength == 0) { SwTextNode* pPrevTextNode = getPrevTextNode(pCurrent); if (!pPrevTextNode) return; - if (pPrevTextNode->GetText().getLength() == 0) + + SwWrtShell* pWrtShell = rDocument.GetDocShell()->GetWrtShell(); + if (pWrtShell && pPrevTextNode->getLayoutFrame(pWrtShell->GetLayout())) { - 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); + if (pPrevTextNode->GetText().getLength() == 0) + { + auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_AVOID_NEWLINES_SPACE), + sfx::AccessibilityIssueID::TEXT_FORMATTING); + pIssue->setIssueObject(IssueObject::TEXT); + pIssue->setNode(pTextNode); + 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++) + SwWrtShell* pWrtShell = rDocument.GetDocShell()->GetWrtShell(); + if (pWrtShell && pTextNode->getLayoutFrame(pWrtShell->GetLayout())) { - auto aChar = sParagraphText[i]; - if (aChar == ' ') + // Check for excess lines inside this paragraph + const OUString& sParagraphText = pTextNode->GetText(); + int nLineCount = 0; + for (sal_Int32 i = 0; i < nParagraphLength; i++) { - nLineCount++; - // Looking for 2 newline characters and above as one can be part of the line - // break after a sentence - if (nLineCount > 2) + auto aChar = sParagraphText[i]; + if (aChar == ' ') { - 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); + 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); + pIssue->setDoc(rDocument); + pIssue->setStart(i); + pIssue->setEnd(i); + } + } + // Don't count carriage return as normal character + else if (aChar != ' ') + { + nLineCount = 0; } - } - // Don't count carriage return as normal character - else if (aChar != ' ') - { - nLineCount = 0; } } } commit 395393408150048b7fd3c7f637edc7fff6a8488c Author: Thorsten Behrens <[email protected]> AuthorDate: Tue Sep 17 04:23:45 2024 +0200 Commit: Gerrit Code Review <[email protected]> CommitDate: Tue Sep 17 04:23:45 2024 +0200 Update git submodules * Update translations from branch 'feature/cib_contract49c' to 977c1be2b7eecf4f8a42eeb991d6d1a48b626bd5 - Translate strings for gallery search Change-Id: I12cb5c10b751df26b33c9a2c658ae3b797a16608 diff --git a/translations b/translations index c85cce3929a1..977c1be2b7ee 160000 --- a/translations +++ b/translations @@ -1 +1 @@ -Subproject commit c85cce3929a1e62e1b1f72950157e9a6d5d9ef93 +Subproject commit 977c1be2b7eecf4f8a42eeb991d6d1a48b626bd5
