diff options
author | Balazs Varga <balazs.varga.extern@allotropia.de> | 2024-11-22 22:03:56 +0100 |
---|---|---|
committer | Balazs Varga <balazs.varga.extern@allotropia.de> | 2024-11-29 12:08:48 +0100 |
commit | 13ac356a32f279a3fd542d62c12e58abe3d3ad30 (patch) | |
tree | 158580a9766ffb11e6393f0fcb9eec4a94c4e560 /sw/source/uibase | |
parent | 7dc626a6cd3895d206320e0ddc1412749d1663a7 (diff) |
tdf#164048 sw a11y: improve error/warning levels with
adding two A11y issue level: Error and warning level, and
categorizing our accesibility issues based on how the
PAC 2024 tools and WCAG behave with the different warnings/errors.
Change-Id: If4e4800497340318bb990326c64de655f24a47e8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177389
Tested-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de>
Tested-by: Jenkins
Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de>
Diffstat (limited to 'sw/source/uibase')
-rw-r--r-- | sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx | 179 | ||||
-rw-r--r-- | sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx | 34 |
2 files changed, 158 insertions, 55 deletions
diff --git a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx index 5e6e934ee598..d5f5f264d657 100644 --- a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx +++ b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx @@ -97,28 +97,9 @@ IMPL_LINK_NOARG(AccessibilityCheckEntry, FixButtonClicked, weld::Button&, void) m_pAccessibilityIssue->quickFixIssue(); } -std::unique_ptr<PanelLayout> A11yCheckIssuesPanel::Create(weld::Widget* pParent, - SfxBindings* pBindings) -{ - if (pParent == nullptr) - throw css::lang::IllegalArgumentException( - u"no parent window given to A11yCheckIssuesPanel::Create"_ustr, nullptr, 0); - return std::make_unique<A11yCheckIssuesPanel>(pParent, pBindings); -} - -A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* pBindings) - : PanelLayout(pParent, u"A11yCheckIssuesPanel"_ustr, - u"modules/swriter/ui/a11ycheckissuespanel.ui"_ustr) - , m_xOptionsButton(m_xBuilder->weld_button(u"bOptions"_ustr)) - , mxAccessibilityBox(m_xBuilder->weld_box(u"accessibilityCheckBox"_ustr)) - , mxUpdateBox(m_xBuilder->weld_box(u"updateBox"_ustr)) - , mxUpdateLinkButton(m_xBuilder->weld_link_button(u"updateLinkButton"_ustr)) - - , mpBindings(pBindings) - , mpDoc(nullptr) - , maA11yCheckController(FN_STAT_ACCESSIBILITY_CHECK, *pBindings, *this) - , mnIssueCount(0) - , mbAutomaticCheckEnabled(false) +AccessibilityCheckLevel::AccessibilityCheckLevel(weld::Box* pParent) + : m_xBuilder(Application::CreateBuilder(pParent, u"svx/ui/accessibilitychecklevel.ui"_ustr)) + , m_xContainer(m_xBuilder->weld_box(u"accessibilityCheckLevelBox"_ustr)) { m_xExpanders[0] = m_xBuilder->weld_expander(u"expand_document"_ustr); m_xExpanders[1] = m_xBuilder->weld_expander(u"expand_styles"_ustr); @@ -143,6 +124,84 @@ A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* p m_xBoxes[8] = m_xBuilder->weld_box(u"box_fakes"_ustr); m_xBoxes[9] = m_xBuilder->weld_box(u"box_numbering"_ustr); m_xBoxes[10] = m_xBuilder->weld_box(u"box_other"_ustr); +} + +void AccessibilityCheckLevel::removeAllEntries() +{ + for (auto eGroup : o3tl::enumrange<AccessibilityCheckGroups>()) + { + auto nGroupIndex = size_t(eGroup); + for (auto const& xEntry : m_aEntries[nGroupIndex]) + m_xBoxes[nGroupIndex]->move(xEntry->get_widget(), nullptr); + } +} + +void AccessibilityCheckLevel::reset() +{ + for (auto& xExpander : m_xExpanders) + xExpander.reset(); + + for (auto& xBox : m_xBoxes) + xBox.reset(); +} + +void AccessibilityCheckLevel::addEntryForGroup( + AccessibilityCheckGroups eGroup, std::vector<sal_Int32>& rIndices, + std::shared_ptr<sfx::AccessibilityIssue> const& pIssue) +{ + auto nGroupIndex = size_t(eGroup); + // prevent the UI locking up forever, this is effectively an O(n^2) situation, given the way the UI additions work + if (m_aEntries[nGroupIndex].size() > 500) + { + SAL_WARN("sw", "too many a11y issues, not adding to panel"); + return; + } + auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxes[nGroupIndex].get(), pIssue); + m_xBoxes[nGroupIndex]->reorder_child(xEntry->get_widget(), rIndices[nGroupIndex]++); + m_aEntries[nGroupIndex].push_back(std::move(xEntry)); +} + +size_t AccessibilityCheckLevel::getEntrySize(AccessibilityCheckGroups eGroup) const +{ + auto nGroupIndex = size_t(eGroup); + return m_aEntries[nGroupIndex].size(); +} + +void AccessibilityCheckLevel::show(size_t nGroupIndex) { m_xExpanders[nGroupIndex]->show(); } + +void AccessibilityCheckLevel::hide(size_t nGroupIndex) { m_xExpanders[nGroupIndex]->hide(); } + +std::unique_ptr<PanelLayout> A11yCheckIssuesPanel::Create(weld::Widget* pParent, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw css::lang::IllegalArgumentException( + u"no parent window given to A11yCheckIssuesPanel::Create"_ustr, nullptr, 0); + return std::make_unique<A11yCheckIssuesPanel>(pParent, pBindings); +} + +A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* pBindings) + : PanelLayout(pParent, u"A11yCheckIssuesPanel"_ustr, + u"modules/swriter/ui/a11ycheckissuespanel.ui"_ustr) + , m_xOptionsButton(m_xBuilder->weld_button(u"bOptions"_ustr)) + , mxUpdateBox(m_xBuilder->weld_box(u"updateBox"_ustr)) + , mxUpdateLinkButton(m_xBuilder->weld_link_button(u"updateLinkButton"_ustr)) + , m_xListSep(m_xBuilder->weld_widget(u"sep_level"_ustr)) + , mpBindings(pBindings) + , mpDoc(nullptr) + , maA11yCheckController(FN_STAT_ACCESSIBILITY_CHECK, *pBindings, *this) + , mnIssueCount(0) + , mbAutomaticCheckEnabled(false) +{ + // errors + m_xLevelExpanders[0] = m_xBuilder->weld_expander(u"expand_errors"_ustr); + mxAccessibilityBox[0] = m_xBuilder->weld_box(u"accessibilityBoxErr"_ustr); + m_aLevelEntries[0] = std::make_unique<AccessibilityCheckLevel>(mxAccessibilityBox[0].get()); + + // warnings + m_xLevelExpanders[1] = m_xBuilder->weld_expander(u"expand_warnings"_ustr); + mxAccessibilityBox[1] = m_xBuilder->weld_box(u"accessibilityBoxWrn"_ustr); + m_aLevelEntries[1] = std::make_unique<AccessibilityCheckLevel>(mxAccessibilityBox[1].get()); mxUpdateLinkButton->connect_activate_link( LINK(this, A11yCheckIssuesPanel, UpdateLinkButtonClicked)); @@ -171,12 +230,14 @@ A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* p // In desktop don't show the update button and schedule to run the accessibility check async if (comphelper::LibreOfficeKit::isActive()) { - mxAccessibilityBox->hide(); + m_xLevelExpanders[0]->hide(); + m_xLevelExpanders[1]->hide(); mxUpdateBox->show(); } else { - mxAccessibilityBox->show(); + m_xLevelExpanders[0]->show(); + m_xLevelExpanders[1]->show(); mxUpdateBox->hide(); Application::PostUserEvent(LINK(this, A11yCheckIssuesPanel, PopulateIssuesHdl)); } @@ -191,7 +252,8 @@ IMPL_LINK_NOARG(A11yCheckIssuesPanel, OptionsButtonClicked, weld::Button&, void) IMPL_LINK_NOARG(A11yCheckIssuesPanel, UpdateLinkButtonClicked, weld::LinkButton&, bool) { - mxAccessibilityBox->show(); + m_xLevelExpanders[0]->show(); + m_xLevelExpanders[1]->show(); mxUpdateBox->hide(); Application::PostUserEvent(LINK(this, A11yCheckIssuesPanel, PopulateIssuesHdl)); return true; @@ -211,44 +273,41 @@ void A11yCheckIssuesPanel::ImplDestroy() mpBindings->Invalidate(SID_ACCESSIBILITY_CHECK_ONLINE); } - for (auto& xExpander : m_xExpanders) - xExpander.reset(); - - for (auto& xBox : m_xBoxes) - xBox.reset(); + for (auto& aLevelEntry : m_aLevelEntries) + { + aLevelEntry->reset(); + aLevelEntry.reset(); + } } A11yCheckIssuesPanel::~A11yCheckIssuesPanel() { suppress_fun_call_w_exception(ImplDestroy()); } void A11yCheckIssuesPanel::removeAllEntries() { - for (auto eGroup : o3tl::enumrange<AccessibilityCheckGroups>()) + for (auto& aLevelEntry : m_aLevelEntries) { - auto nGroupIndex = size_t(eGroup); - for (auto const& xEntry : m_aEntries[nGroupIndex]) - m_xBoxes[nGroupIndex]->move(xEntry->get_widget(), nullptr); + aLevelEntry->removeAllEntries(); } } void A11yCheckIssuesPanel::addEntryForGroup(AccessibilityCheckGroups eGroup, - std::vector<sal_Int32>& rIndices, + std::vector<std::vector<sal_Int32>>& rIndices, std::shared_ptr<sfx::AccessibilityIssue> const& pIssue) { - auto nGroupIndex = size_t(eGroup); // prevent the UI locking up forever, this is effectively an O(n^2) situation, given the way the UI additions work - if (m_aEntries[nGroupIndex].size() > 500) + if (m_aLevelEntries[0]->getEntrySize(eGroup) + m_aLevelEntries[1]->getEntrySize(eGroup) > 500) { SAL_WARN("sw", "too many a11y issues, not adding to panel"); return; } - auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxes[nGroupIndex].get(), pIssue); - m_xBoxes[nGroupIndex]->reorder_child(xEntry->get_widget(), rIndices[nGroupIndex]++); - m_aEntries[nGroupIndex].push_back(std::move(xEntry)); + + size_t nLevel = static_cast<size_t>(pIssue->m_eIssueLvl); + m_aLevelEntries[nLevel]->addEntryForGroup(eGroup, rIndices[nLevel], pIssue); } void A11yCheckIssuesPanel::populateIssues() { - if (!mpDoc || !mxAccessibilityBox->is_visible()) + if (!mpDoc || !(m_xLevelExpanders[0]->is_visible() || m_xLevelExpanders[1]->is_visible())) return; SfxViewShell* pViewShell = SfxViewShell::Current(); @@ -263,7 +322,7 @@ void A11yCheckIssuesPanel::populateIssues() removeAllEntries(); - std::vector<sal_Int32> nIndices(11, 0); + std::vector<std::vector<sal_Int32>> nIndices(2, std::vector<sal_Int32>(11, 0)); sal_Int32 nDirectFormats = 0; for (std::shared_ptr<sfx::AccessibilityIssue> const& pIssue : m_aIssueCollection.getIssues()) @@ -368,23 +427,43 @@ void A11yCheckIssuesPanel::populateIssues() } } - // add DirectFormats (if have) as last element to Formatting AccessibilityCheckGroup + // add DirectFormats (if have) as last element to Formatting AccessibilityCheckGroup on the Warning level if (nDirectFormats > 0) { size_t nGroupFormatIndex = size_t(AccessibilityCheckGroups::Formatting); - nIndices[nGroupFormatIndex]++; + // Direct Formats are on the warning level + size_t nLevel = static_cast<size_t>(sfx::AccessibilityIssueLevel::WARNLEV); + nIndices[nLevel][nGroupFormatIndex]++; } - size_t nGroupIndex = 0; - for (sal_Int32 nIndex : nIndices) + for (auto eLevel : o3tl::enumrange<sfx::AccessibilityIssueLevel>()) { - if (nIndex > 0) - m_xExpanders[nGroupIndex]->show(); + size_t nGroupIndex = 0; + auto nLevelIndex = size_t(eLevel); + bool bHaveIssue = false; + for (sal_Int32 nIndex : nIndices[nLevelIndex]) + { + if (nIndex > 0) + { + m_aLevelEntries[nLevelIndex]->show(nGroupIndex); + if (!bHaveIssue) + bHaveIssue = true; + } + else + m_aLevelEntries[nLevelIndex]->hide(nGroupIndex); + nGroupIndex++; + } + if (!bHaveIssue) + m_xLevelExpanders[nLevelIndex]->hide(); else - m_xExpanders[nGroupIndex]->hide(); - nGroupIndex++; + m_xLevelExpanders[nLevelIndex]->show(); } + if (m_xLevelExpanders[0]->is_visible() && m_xLevelExpanders[1]->is_visible()) + m_xListSep->set_visible(true); + else + m_xListSep->set_visible(false); + if (pWindow) pWindow->SetPointer(PointerStyle::Arrow); } diff --git a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx index f961778c4b27..b293cb937953 100644 --- a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx +++ b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx @@ -59,6 +59,29 @@ enum class AccessibilityCheckGroups : size_t LAST = Other }; +class AccessibilityCheckLevel +{ +private: + std::unique_ptr<weld::Builder> m_xBuilder; + std::unique_ptr<weld::Box> m_xContainer; + std::array<std::vector<std::unique_ptr<AccessibilityCheckEntry>>, 11> m_aEntries; + std::array<std::unique_ptr<weld::Expander>, 11> m_xExpanders; + std::array<std::unique_ptr<weld::Box>, 11> m_xBoxes; + +public: + AccessibilityCheckLevel(weld::Box* pParent); + + void removeAllEntries(); + void reset(); + + void addEntryForGroup(AccessibilityCheckGroups eGroup, std::vector<sal_Int32>& rIndices, + std::shared_ptr<sfx::AccessibilityIssue> const& pIssue); + size_t getEntrySize(AccessibilityCheckGroups eGroup) const; + + void show(size_t nGroupIndex); + void hide(size_t nGroupIndex); +}; + class A11yCheckIssuesPanel : public PanelLayout, public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface { @@ -76,13 +99,13 @@ public: virtual ~A11yCheckIssuesPanel() override; private: - std::array<std::vector<std::unique_ptr<AccessibilityCheckEntry>>, 11> m_aEntries; - std::array<std::unique_ptr<weld::Expander>, 11> m_xExpanders; - std::array<std::unique_ptr<weld::Box>, 11> m_xBoxes; std::unique_ptr<weld::Button> m_xOptionsButton; - std::unique_ptr<weld::Box> mxAccessibilityBox; + std::array<std::unique_ptr<weld::Expander>, 2> m_xLevelExpanders; + std::array<std::unique_ptr<weld::Box>, 2> mxAccessibilityBox; + std::array<std::unique_ptr<AccessibilityCheckLevel>, 2> m_aLevelEntries; std::unique_ptr<weld::Box> mxUpdateBox; std::unique_ptr<weld::LinkButton> mxUpdateLinkButton; + std::unique_ptr<weld::Widget> m_xListSep; sfx::AccessibilityIssueCollection m_aIssueCollection; void removeAllEntries(); @@ -92,7 +115,8 @@ private: DECL_LINK(UpdateLinkButtonClicked, weld::LinkButton&, bool); DECL_LINK(PopulateIssuesHdl, void*, void); - void addEntryForGroup(AccessibilityCheckGroups eGroup, std::vector<sal_Int32>& rIndices, + void addEntryForGroup(AccessibilityCheckGroups eGroup, + std::vector<std::vector<sal_Int32>>& rIndices, std::shared_ptr<sfx::AccessibilityIssue> const& pIssue); SfxBindings* GetBindings() { return mpBindings; } |