summaryrefslogtreecommitdiffstats
path: root/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx')
-rw-r--r--sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx377
1 files changed, 377 insertions, 0 deletions
diff --git a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx
new file mode 100644
index 0000000000..a1907c9b63
--- /dev/null
+++ b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx
@@ -0,0 +1,377 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <sal/config.h>
+
+#include <AccessibilityCheck.hxx>
+#include <AccessibilityIssue.hxx>
+#include <cmdid.h>
+#include <doc.hxx>
+#include <docsh.hxx>
+#include <ndtxt.hxx>
+#include <wrtsh.hxx>
+
+#include <officecfg/Office/Common.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/AccessibilityIssue.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/svapp.hxx>
+
+#include "A11yCheckIssuesPanel.hxx"
+
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+namespace sw::sidebar
+{
+AccessibilityCheckEntry::AccessibilityCheckEntry(
+ weld::Container* pParent, std::shared_ptr<sfx::AccessibilityIssue> const& rAccessibilityIssue)
+ : m_xBuilder(Application::CreateBuilder(pParent, "svx/ui/accessibilitycheckentry.ui"))
+ , m_xContainer(m_xBuilder->weld_container("accessibilityCheckEntryBox"))
+ , m_xLabel(m_xBuilder->weld_label("accessibilityCheckEntryLabel"))
+ , m_xGotoButton(m_xBuilder->weld_link_button("accessibilityCheckEntryLinkButton"))
+ , m_xFixButton(m_xBuilder->weld_button("accessibilityCheckEntryFixButton"))
+ , m_pAccessibilityIssue(rAccessibilityIssue)
+{
+ // lock in the height as including the button so all rows are the same height
+ m_xContainer->set_size_request(-1, m_xContainer->get_preferred_size().Height());
+
+ if (m_pAccessibilityIssue->canGotoIssue())
+ {
+ m_xGotoButton->set_label(m_pAccessibilityIssue->m_aIssueText);
+
+ // tdf#156137 allow LinkButton label to wrap
+ int nMaxWidth = m_xGotoButton->get_approximate_digit_width() * 10;
+ m_xGotoButton->set_label_wrap(true);
+ m_xGotoButton->set_size_request(nMaxWidth, -1);
+
+ m_xGotoButton->connect_activate_link(
+ LINK(this, AccessibilityCheckEntry, GotoButtonClicked));
+
+ // add full path of linked graphic as tooltip,
+ if (m_pAccessibilityIssue->m_eIssueID == sfx::AccessibilityIssueID::LINKED_GRAPHIC)
+ {
+ auto pSwIssue = std::static_pointer_cast<sw::AccessibilityIssue>(m_pAccessibilityIssue);
+ auto aInfo = pSwIssue->getAdditionalInfo();
+ if (aInfo.size() > 0)
+ {
+ m_xGotoButton->set_tooltip_text(aInfo[0]);
+ }
+ }
+
+ m_xLabel->set_visible(false);
+ }
+ else
+ {
+ m_xLabel->set_label(m_pAccessibilityIssue->m_aIssueText);
+ m_xGotoButton->set_visible(false);
+ }
+
+ m_xFixButton->set_visible(m_pAccessibilityIssue->canQuickFixIssue());
+ m_xFixButton->connect_clicked(LINK(this, AccessibilityCheckEntry, FixButtonClicked));
+
+ m_pAccessibilityIssue->setParent(dynamic_cast<weld::Window*>(get_widget()));
+}
+
+IMPL_LINK_NOARG(AccessibilityCheckEntry, GotoButtonClicked, weld::LinkButton&, bool)
+{
+ m_pAccessibilityIssue->gotoIssue();
+ return true;
+}
+
+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 ::com::sun::star::lang::IllegalArgumentException(
+ "no parent window given to A11yCheckIssuesPanel::Create", nullptr, 0);
+ return std::make_unique<A11yCheckIssuesPanel>(pParent, pBindings);
+}
+
+A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* pBindings)
+ : PanelLayout(pParent, "A11yCheckIssuesPanel", "modules/swriter/ui/a11ycheckissuespanel.ui")
+ , m_xExpanderDocument(m_xBuilder->weld_expander("expand_document"))
+ , m_xExpanderStyles(m_xBuilder->weld_expander("expand_styles"))
+ , m_xExpanderLinked(m_xBuilder->weld_expander("expand_linked"))
+ , m_xExpanderNoAlt(m_xBuilder->weld_expander("expand_no_alt"))
+ , m_xExpanderTable(m_xBuilder->weld_expander("expand_table"))
+ , m_xExpanderFormatting(m_xBuilder->weld_expander("expand_formatting"))
+ , m_xExpanderHyperlink(m_xBuilder->weld_expander("expand_hyperlink"))
+ , m_xExpanderFakes(m_xBuilder->weld_expander("expand_fakes"))
+ , m_xExpanderNumbering(m_xBuilder->weld_expander("expand_numbering"))
+ , m_xExpanderOther(m_xBuilder->weld_expander("expand_other"))
+ , m_xBoxDocument(m_xBuilder->weld_box("box_document"))
+ , m_xBoxStyles(m_xBuilder->weld_box("box_styles"))
+ , m_xBoxLinked(m_xBuilder->weld_box("box_linked"))
+ , m_xBoxNoAlt(m_xBuilder->weld_box("box_no_alt"))
+ , m_xBoxTable(m_xBuilder->weld_box("box_table"))
+ , m_xBoxFormatting(m_xBuilder->weld_box("box_formatting"))
+ , m_xBoxHyperlink(m_xBuilder->weld_box("box_hyperlink"))
+ , m_xBoxFakes(m_xBuilder->weld_box("box_fakes"))
+ , m_xBoxNumbering(m_xBuilder->weld_box("box_numbering"))
+ , m_xBoxOther(m_xBuilder->weld_box("box_other"))
+ , mpBindings(pBindings)
+ , mpDoc(nullptr)
+ , maA11yCheckController(FN_STAT_ACCESSIBILITY_CHECK, *pBindings, *this)
+ , mnIssueCount(0)
+ , mbAutomaticCheckEnabled(false)
+{
+ SwDocShell* pDocSh = dynamic_cast<SwDocShell*>(SfxObjectShell::Current());
+ if (!pDocSh)
+ return;
+
+ // Automatic a11y checking must be enabled for this panel to work properly
+ mbAutomaticCheckEnabled
+ = officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::get();
+ if (!mbAutomaticCheckEnabled)
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::set(true, batch);
+ batch->commit();
+ pBindings->Invalidate(SID_ACCESSIBILITY_CHECK_ONLINE);
+ }
+
+ mpDoc = pDocSh->GetDoc();
+
+ populateIssues();
+}
+
+void A11yCheckIssuesPanel::ImplDestroy()
+{
+ // Restore state when this panel is no longer used
+ if (!mbAutomaticCheckEnabled)
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::set(false, batch);
+ batch->commit();
+ mpBindings->Invalidate(SID_ACCESSIBILITY_CHECK_ONLINE);
+ }
+ m_xExpanderDocument.reset();
+ m_xExpanderStyles.reset();
+ m_xExpanderLinked.reset();
+ m_xExpanderNoAlt.reset();
+ m_xExpanderTable.reset();
+ m_xExpanderFormatting.reset();
+ m_xExpanderHyperlink.reset();
+ m_xExpanderFakes.reset();
+ m_xExpanderNumbering.reset();
+ m_xExpanderOther.reset();
+ m_xBoxDocument.reset();
+ m_xBoxStyles.reset();
+ m_xBoxLinked.reset();
+ m_xBoxNoAlt.reset();
+ m_xBoxTable.reset();
+ m_xBoxFormatting.reset();
+ m_xBoxHyperlink.reset();
+ m_xBoxFakes.reset();
+ m_xBoxNumbering.reset();
+ m_xBoxOther.reset();
+}
+
+A11yCheckIssuesPanel::~A11yCheckIssuesPanel() { suppress_fun_call_w_exception(ImplDestroy()); }
+
+void A11yCheckIssuesPanel::removeOldWidgets()
+{
+ for (auto const& xEntry : m_aDocumentEntries)
+ m_xBoxDocument->move(xEntry->get_widget(), nullptr);
+ m_xExpanderDocument->set_visible(false);
+
+ for (auto const& xEntry : m_aStylesEntries)
+ m_xBoxStyles->move(xEntry->get_widget(), nullptr);
+ m_xExpanderStyles->set_visible(false);
+
+ for (auto const& xEntry : m_aLinkedEntries)
+ m_xBoxLinked->move(xEntry->get_widget(), nullptr);
+ m_xExpanderLinked->set_visible(false);
+
+ for (auto const& xEntry : m_aNoAltEntries)
+ m_xBoxNoAlt->move(xEntry->get_widget(), nullptr);
+ m_xExpanderNoAlt->set_visible(false);
+
+ for (auto const& xEntry : m_aTableEntries)
+ m_xBoxTable->move(xEntry->get_widget(), nullptr);
+ m_xExpanderTable->set_visible(false);
+
+ for (auto const& xEntry : m_aFormattingEntries)
+ m_xBoxFormatting->move(xEntry->get_widget(), nullptr);
+ m_xExpanderFormatting->set_visible(false);
+
+ for (auto const& xEntry : m_aHyperlinkEntries)
+ m_xBoxHyperlink->move(xEntry->get_widget(), nullptr);
+ m_xExpanderHyperlink->set_visible(false);
+
+ for (auto const& xEntry : m_aFakesEntries)
+ m_xBoxFakes->move(xEntry->get_widget(), nullptr);
+ m_xExpanderFakes->set_visible(false);
+
+ for (auto const& xEntry : m_aNumberingEntries)
+ m_xBoxNumbering->move(xEntry->get_widget(), nullptr);
+ m_xExpanderNumbering->set_visible(false);
+
+ for (auto const& xEntry : m_aOtherEntries)
+ m_xBoxOther->move(xEntry->get_widget(), nullptr);
+ m_xExpanderOther->set_visible(false);
+}
+
+void A11yCheckIssuesPanel::populateIssues()
+{
+ if (!mpDoc)
+ return;
+ sw::AccessibilityCheck aCheck(mpDoc);
+ aCheck.check();
+ m_aIssueCollection = aCheck.getIssueCollection();
+
+ removeOldWidgets();
+
+ sal_Int32 iDocument = 0;
+ sal_Int32 iStyles = 0;
+ sal_Int32 iLinked = 0;
+ sal_Int32 iNoAlt = 0;
+ sal_Int32 iTable = 0;
+ sal_Int32 iFormatting = 0;
+ sal_Int32 iHyperlink = 0;
+ sal_Int32 iFakes = 0;
+ sal_Int32 iNumbering = 0;
+ sal_Int32 iOther = 0;
+ for (std::shared_ptr<sfx::AccessibilityIssue> const& pIssue : m_aIssueCollection.getIssues())
+ {
+ switch (pIssue->m_eIssueID)
+ {
+ case sfx::AccessibilityIssueID::DOCUMENT_TITLE:
+ case sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE:
+ case sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND:
+ {
+ auto xEntry
+ = std::make_unique<AccessibilityCheckEntry>(m_xBoxDocument.get(), pIssue);
+ m_xBoxDocument->reorder_child(xEntry->get_widget(), iDocument++);
+ m_xExpanderDocument->set_visible(true);
+ m_aDocumentEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::STYLE_LANGUAGE:
+ {
+ auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxStyles.get(), pIssue);
+ m_xBoxStyles->reorder_child(xEntry->get_widget(), iStyles++);
+ m_xExpanderStyles->set_visible(true);
+ m_aStylesEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::LINKED_GRAPHIC:
+ {
+ auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxLinked.get(), pIssue);
+ m_xBoxLinked->reorder_child(xEntry->get_widget(), iLinked++);
+ m_xExpanderLinked->set_visible(true);
+ m_aLinkedEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::NO_ALT_OLE:
+ case sfx::AccessibilityIssueID::NO_ALT_GRAPHIC:
+ case sfx::AccessibilityIssueID::NO_ALT_SHAPE:
+ {
+ auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxNoAlt.get(), pIssue);
+ m_xBoxNoAlt->reorder_child(xEntry->get_widget(), iNoAlt++);
+ m_xExpanderNoAlt->set_visible(true);
+ m_aNoAltEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::TABLE_MERGE_SPLIT:
+ {
+ auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxTable.get(), pIssue);
+ m_xBoxTable->reorder_child(xEntry->get_widget(), iTable++);
+ m_xExpanderTable->set_visible(true);
+ m_aTableEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::TEXT_FORMATTING:
+ case sfx::AccessibilityIssueID::TABLE_FORMATTING:
+ {
+ auto xEntry
+ = std::make_unique<AccessibilityCheckEntry>(m_xBoxFormatting.get(), pIssue);
+ m_xBoxFormatting->reorder_child(xEntry->get_widget(), iFormatting++);
+ m_xExpanderFormatting->set_visible(true);
+ m_aFormattingEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT:
+ case sfx::AccessibilityIssueID::HYPERLINK_SHORT:
+ {
+ auto xEntry
+ = std::make_unique<AccessibilityCheckEntry>(m_xBoxHyperlink.get(), pIssue);
+ m_xBoxHyperlink->reorder_child(xEntry->get_widget(), iHyperlink++);
+ m_xExpanderHyperlink->set_visible(true);
+ m_aHyperlinkEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::FAKE_FOOTNOTE:
+ case sfx::AccessibilityIssueID::FAKE_CAPTION:
+ {
+ auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxFakes.get(), pIssue);
+ m_xBoxFakes->reorder_child(xEntry->get_widget(), iFakes++);
+ m_xExpanderFakes->set_visible(true);
+ m_aFakesEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::MANUAL_NUMBERING:
+ {
+ auto xEntry
+ = std::make_unique<AccessibilityCheckEntry>(m_xBoxNumbering.get(), pIssue);
+ m_xBoxNumbering->reorder_child(xEntry->get_widget(), iNumbering++);
+ m_xExpanderNumbering->set_visible(true);
+ m_aNumberingEntries.push_back(std::move(xEntry));
+ }
+ break;
+ case sfx::AccessibilityIssueID::UNSPECIFIED:
+ {
+ auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxOther.get(), pIssue);
+ m_xBoxOther->reorder_child(xEntry->get_widget(), iOther++);
+ m_xExpanderOther->set_visible(true);
+ m_aOtherEntries.push_back(std::move(xEntry));
+ }
+ break;
+ default:
+ {
+ SAL_WARN("sw.a11y", "Invalid issue ID.");
+ continue;
+ }
+ break;
+ };
+ }
+}
+
+void A11yCheckIssuesPanel::NotifyItemUpdate(const sal_uInt16 nSid, const SfxItemState /* eState */,
+ const SfxPoolItem* pState)
+{
+ if (!pState) //disposed
+ return;
+
+ switch (nSid)
+ {
+ case FN_STAT_ACCESSIBILITY_CHECK:
+ {
+ sal_Int32 nIssueCount = static_cast<const SfxInt32Item*>(pState)->GetValue();
+ if (nIssueCount != mnIssueCount)
+ {
+ mnIssueCount = nIssueCount;
+ populateIssues();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */